recker 1.0.79 → 1.0.80-next.70ea84d
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/browser/browser/mini.d.ts +2 -2
- package/dist/browser/browser/recker-mini.d.ts +8 -8
- package/dist/browser/browser/recker.d.ts +11 -8
- package/dist/browser/browser/recker.js +54 -6
- package/dist/browser/core/client.d.ts +15 -10
- package/dist/browser/core/client.js +54 -38
- package/dist/browser/index.iife.min.js +129 -130
- package/dist/browser/index.min.js +129 -130
- package/dist/browser/index.mini.iife.js +5697 -636
- package/dist/browser/index.mini.iife.min.js +47 -48
- package/dist/browser/index.mini.min.js +47 -48
- package/dist/browser/index.mini.umd.js +5697 -636
- package/dist/browser/index.mini.umd.min.js +47 -48
- package/dist/browser/index.umd.min.js +129 -130
- package/dist/browser/mini.d.ts +2 -2
- package/dist/browser/plugins/proxy-rotator.d.ts +2 -2
- package/dist/browser/plugins/proxy-rotator.js +6 -28
- package/dist/browser/recker-mini.d.ts +8 -8
- package/dist/browser/recker.d.ts +11 -8
- package/dist/browser/recker.js +54 -6
- package/dist/browser/scrape/document.js +2 -2
- package/dist/browser/scrape/element.js +7 -1
- package/dist/browser/scrape/parser/nodes/html.js +1 -1
- package/dist/browser/scrape/spider.d.ts +52 -0
- package/dist/browser/scrape/spider.js +620 -38
- package/dist/browser/scrape/types.d.ts +2 -0
- package/dist/browser/search/google.d.ts +26 -1
- package/dist/browser/search/google.js +427 -45
- package/dist/browser/seo/analyzer.d.ts +1 -0
- package/dist/browser/seo/analyzer.js +144 -1
- package/dist/browser/seo/index.d.ts +1 -1
- package/dist/browser/seo/keyword-campaign-analyzer.d.ts +2 -0
- package/dist/browser/seo/keyword-campaign-analyzer.js +538 -0
- package/dist/browser/seo/keyword-campaign-seed-advanced.d.ts +17 -0
- package/dist/browser/seo/keyword-campaign-seed-advanced.js +269 -0
- package/dist/browser/seo/keyword-campaign-seed-core.d.ts +29 -0
- package/dist/browser/seo/keyword-campaign-seed-core.js +525 -0
- package/dist/browser/seo/keyword-campaign-shared.d.ts +165 -0
- package/dist/browser/seo/keyword-campaign-shared.js +59 -0
- package/dist/browser/seo/keyword-campaign.d.ts +4 -107
- package/dist/browser/seo/keyword-campaign.js +2 -380
- package/dist/browser/seo/keywords.js +5 -22
- package/dist/browser/seo/types.d.ts +19 -0
- package/dist/browser/transport/curl.d.ts +5 -1
- package/dist/browser/transport/curl.js +207 -50
- package/dist/browser/transport/undici.d.ts +4 -3
- package/dist/browser/transport/undici.js +123 -49
- package/dist/browser/types/index.d.ts +9 -3
- package/dist/browser/utils/binary-manager.js +26 -3
- package/dist/browser/utils/block-detector.d.ts +8 -0
- package/dist/browser/utils/block-detector.js +542 -7
- package/dist/cli/commands/hls-runner.js +5 -4
- package/dist/cli/commands/live-runner.js +5 -4
- package/dist/cli/commands/loadtest-runner.js +3 -2
- package/dist/cli/commands/search.d.ts +2 -0
- package/dist/cli/commands/search.js +105 -0
- package/dist/cli/commands/seo-runner.js +9 -7
- package/dist/cli/commands/seo.js +140 -1
- package/dist/cli/commands/serve.js +75 -131
- package/dist/cli/commands/server-runner.js +59 -82
- package/dist/cli/commands/spider-runner.d.ts +37 -1
- package/dist/cli/commands/spider-runner.js +134 -10
- package/dist/cli/commands/spider.d.ts +18 -1
- package/dist/cli/commands/spider.js +457 -27
- package/dist/cli/events/handlers/cli.js +30 -1
- package/dist/cli/events/handlers/tui.js +26 -0
- package/dist/cli/events/types.d.ts +27 -0
- package/dist/cli/handler.d.ts +2 -12
- package/dist/cli/handler.js +20 -15
- package/dist/cli/handlers/protocols.js +39 -12
- package/dist/cli/handlers/search.d.ts +2 -0
- package/dist/cli/handlers/search.js +171 -0
- package/dist/cli/handlers/seo-analyze.d.ts +1 -0
- package/dist/cli/handlers/seo-analyze.js +666 -0
- package/dist/cli/handlers/seo-robots.d.ts +1 -0
- package/dist/cli/handlers/seo-robots.js +76 -0
- package/dist/cli/handlers/seo-serp.d.ts +54 -0
- package/dist/cli/handlers/seo-serp.js +243 -0
- package/dist/cli/handlers/seo-sitemap.d.ts +1 -0
- package/dist/cli/handlers/seo-sitemap.js +55 -0
- package/dist/cli/handlers/seo-spider.d.ts +1 -0
- package/dist/cli/handlers/seo-spider.js +334 -0
- package/dist/cli/handlers/seo.d.ts +8 -4
- package/dist/cli/handlers/seo.js +294 -442
- package/dist/cli/handlers/spider.js +94 -17
- package/dist/cli/handlers/streaming.js +5 -1
- package/dist/cli/index.js +11 -2
- package/dist/cli/presets.d.ts +1 -1
- package/dist/cli/presets.js +15 -4
- package/dist/cli/tui/app.js +6 -1
- package/dist/cli/tui/components/rich-response.d.ts +72 -0
- package/dist/cli/tui/components/rich-response.js +117 -0
- package/dist/cli/tui/executor-commands/background.js +30 -24
- package/dist/cli/tui/executor-commands/testing.js +3 -2
- package/dist/cli/tui/hooks/useDomains.d.ts +17 -0
- package/dist/cli/tui/hooks/useHelp.js +15 -2
- package/dist/cli/tui/job-manager.d.ts +4 -4
- package/dist/cli/tui/job-manager.js +5 -1
- package/dist/cli/tui/spider-tui.d.ts +63 -0
- package/dist/cli/tui/spider-tui.js +120 -2
- package/dist/cli/types.d.ts +12 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utils/option-helpers.d.ts +10 -0
- package/dist/cli/utils/option-helpers.js +63 -0
- package/dist/cli/utils/score-color.d.ts +11 -0
- package/dist/cli/utils/score-color.js +11 -0
- package/dist/cli/utils/serp-campaign.d.ts +53 -0
- package/dist/cli/utils/serp-campaign.js +53 -0
- package/dist/cli/utils/serp-config.d.ts +26 -0
- package/dist/cli/utils/serp-config.js +125 -0
- package/dist/core/client.d.ts +15 -10
- package/dist/core/client.js +54 -38
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mcp/cli.js +35 -34
- package/dist/mcp/client.d.ts +2 -2
- package/dist/mcp/client.js +20 -2
- package/dist/mcp/contract.d.ts +1 -1
- package/dist/mcp/profiles.js +5 -1
- package/dist/mcp/prompts/index.js +8 -4
- package/dist/mcp/resources/index.js +46 -23
- package/dist/mcp/server.js +9 -6
- package/dist/mcp/tools/protocols.js +9 -2
- package/dist/mcp/tools/registry.js +13 -3
- package/dist/mcp/tools/seo.js +427 -2
- package/dist/mcp/types.d.ts +5 -1
- package/dist/plugins/proxy-rotator.d.ts +2 -2
- package/dist/plugins/proxy-rotator.js +6 -28
- package/dist/raffel/client.d.ts +38 -0
- package/dist/raffel/client.js +282 -0
- package/dist/raffel/index.d.ts +2 -0
- package/dist/raffel/index.js +2 -0
- package/dist/raffel/types.d.ts +40 -0
- package/dist/raffel/types.js +14 -0
- package/dist/recker.d.ts +13 -7
- package/dist/recker.js +58 -6
- package/dist/scrape/document.js +2 -2
- package/dist/scrape/element.js +7 -1
- package/dist/scrape/parser/nodes/html.js +1 -1
- package/dist/scrape/spider.d.ts +52 -0
- package/dist/scrape/spider.js +620 -38
- package/dist/scrape/types.d.ts +2 -0
- package/dist/search/google.d.ts +26 -1
- package/dist/search/google.js +427 -45
- package/dist/search/index.d.ts +1 -1
- package/dist/seo/analyzer.d.ts +1 -0
- package/dist/seo/analyzer.js +144 -1
- package/dist/seo/index.d.ts +1 -1
- package/dist/seo/keyword-campaign-analyzer.d.ts +2 -0
- package/dist/seo/keyword-campaign-analyzer.js +538 -0
- package/dist/seo/keyword-campaign-seed-advanced.d.ts +17 -0
- package/dist/seo/keyword-campaign-seed-advanced.js +269 -0
- package/dist/seo/keyword-campaign-seed-core.d.ts +29 -0
- package/dist/seo/keyword-campaign-seed-core.js +525 -0
- package/dist/seo/keyword-campaign-shared.d.ts +165 -0
- package/dist/seo/keyword-campaign-shared.js +59 -0
- package/dist/seo/keyword-campaign.d.ts +4 -107
- package/dist/seo/keyword-campaign.js +2 -380
- package/dist/seo/keywords.js +5 -22
- package/dist/seo/types.d.ts +19 -0
- package/dist/template/index.d.ts +1 -1
- package/dist/template/types.d.ts +0 -2
- package/dist/testing/index.d.ts +1 -22
- package/dist/testing/index.js +1 -11
- package/dist/transport/curl.d.ts +5 -1
- package/dist/transport/curl.js +207 -50
- package/dist/transport/undici.d.ts +4 -3
- package/dist/transport/undici.js +123 -49
- package/dist/types/index.d.ts +9 -3
- package/dist/utils/binary-manager.js +26 -3
- package/dist/utils/block-detector.d.ts +8 -0
- package/dist/utils/block-detector.js +542 -7
- package/dist/version.js +1 -1
- package/package.json +12 -1
- package/dist/testing/mock-dns-server.d.ts +0 -69
- package/dist/testing/mock-dns-server.js +0 -269
- package/dist/testing/mock-ftp-server.d.ts +0 -89
- package/dist/testing/mock-ftp-server.js +0 -562
- package/dist/testing/mock-hls-server.d.ts +0 -80
- package/dist/testing/mock-hls-server.js +0 -381
- package/dist/testing/mock-http-server.d.ts +0 -124
- package/dist/testing/mock-http-server.js +0 -343
- package/dist/testing/mock-proxy-server.d.ts +0 -108
- package/dist/testing/mock-proxy-server.js +0 -615
- package/dist/testing/mock-sse-server.d.ts +0 -76
- package/dist/testing/mock-sse-server.js +0 -291
- package/dist/testing/mock-telnet-server.d.ts +0 -59
- package/dist/testing/mock-telnet-server.js +0 -274
- package/dist/testing/mock-udp-server.d.ts +0 -43
- package/dist/testing/mock-udp-server.js +0 -188
- package/dist/testing/mock-websocket-server.d.ts +0 -76
- package/dist/testing/mock-websocket-server.js +0 -334
- package/dist/testing/mock-whois-server.d.ts +0 -56
- package/dist/testing/mock-whois-server.js +0 -234
- package/dist/testing/proxy-certs.d.ts +0 -19
- package/dist/testing/proxy-certs.js +0 -208
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { runCrawlerSerpCampaign } from '../handlers/seo.js';
|
|
2
|
+
export async function runSpiderKeywordCampaign(targetUrl, pages, config) {
|
|
3
|
+
const normalizedPages = pages.map((page) => ({
|
|
4
|
+
url: page.url,
|
|
5
|
+
seoReport: page.seoReport,
|
|
6
|
+
}));
|
|
7
|
+
return runCrawlerSerpCampaign(targetUrl, normalizedPages, config);
|
|
8
|
+
}
|
|
9
|
+
function toKeywordCampaignResult(item) {
|
|
10
|
+
return {
|
|
11
|
+
keyword: item.keyword,
|
|
12
|
+
found: Boolean(item.found),
|
|
13
|
+
position: item.bestPosition,
|
|
14
|
+
targetUrl: item.matchedUrl,
|
|
15
|
+
searchUrl: item.searchUrl,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function toSerpSeedMap(plan) {
|
|
19
|
+
return plan.map((seed) => ({
|
|
20
|
+
keyword: seed.keyword,
|
|
21
|
+
sourcePage: seed.sourcePage,
|
|
22
|
+
sourceWeight: seed.sourceWeight,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
export function toSerpPayload(campaign) {
|
|
26
|
+
return {
|
|
27
|
+
summary: {
|
|
28
|
+
queriesRequested: campaign.campaign.summary.queriesRequested,
|
|
29
|
+
queriesExecuted: campaign.campaign.summary.queriesExecuted,
|
|
30
|
+
queriesFound: campaign.campaign.summary.queriesFound,
|
|
31
|
+
avgTopPosition: campaign.campaign.summary.avgTopPosition,
|
|
32
|
+
top3Count: campaign.campaign.summary.top3Count,
|
|
33
|
+
top10Count: campaign.campaign.summary.top10Count,
|
|
34
|
+
topOrganicCompetitors: campaign.campaign.summary.topOrganicCompetitors,
|
|
35
|
+
},
|
|
36
|
+
campaign: campaign.campaign.campaign,
|
|
37
|
+
results: campaign.campaign.results.slice(0, 12).map((item) => toKeywordCampaignResult(item)),
|
|
38
|
+
pageComparison: campaign.campaign.pageComparison.map((item) => ({
|
|
39
|
+
pageUrl: item.pageUrl,
|
|
40
|
+
tracked: item.tracked,
|
|
41
|
+
found: item.found,
|
|
42
|
+
appearanceRate: `${item.appearanceRate.toFixed(1)}%`,
|
|
43
|
+
avgPosition: item.avgPosition === null ? 'n/a' : String(item.avgPosition),
|
|
44
|
+
top3: item.top3,
|
|
45
|
+
top10: item.top10,
|
|
46
|
+
})),
|
|
47
|
+
seedPlan: {
|
|
48
|
+
short: toSerpSeedMap(campaign.plan.short),
|
|
49
|
+
longTail: toSerpSeedMap(campaign.plan.longTail),
|
|
50
|
+
ordered: toSerpSeedMap(campaign.plan.ordered),
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GoogleSearchAdvancedOptions } from '../../search/google.js';
|
|
2
|
+
export declare const DEFAULT_SERP_KEYWORD_LIMIT = 5;
|
|
3
|
+
export declare const DEFAULT_SERP_MAX_RESULTS = 10;
|
|
4
|
+
export declare const DEFAULT_SERP_CONCURRENCY = 1;
|
|
5
|
+
export declare const DEFAULT_SERP_DELAY_MS = 1200;
|
|
6
|
+
export declare const DEFAULT_SERP_JITTER_MS = 450;
|
|
7
|
+
export declare const DEFAULT_SERP_CAPTCHA_COOLDOWN_MS = 2400;
|
|
8
|
+
export declare const DEFAULT_SERP_MAX_CONSECUTIVE_BLOCKS = 3;
|
|
9
|
+
export declare const DEFAULT_SERP_RETRY_COUNT = 1;
|
|
10
|
+
export declare const DEFAULT_SERP_RETRY_DELAY_MS = 1200;
|
|
11
|
+
export declare const DEFAULT_SERP_HUMAN_PROFILE: 'chrome' | 'off';
|
|
12
|
+
export interface SpiderSerpOptionConfig {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
topKeywordsLimit: number;
|
|
15
|
+
queriesLimit: number;
|
|
16
|
+
resultsPerQuery: number;
|
|
17
|
+
searchConcurrency: number;
|
|
18
|
+
searchDelayMs: number;
|
|
19
|
+
searchDelayJitterMs: number;
|
|
20
|
+
searchCaptchaCooldownMs: number;
|
|
21
|
+
searchMaxConsecutiveBlocks?: number;
|
|
22
|
+
searchRetryCount: number;
|
|
23
|
+
searchRetryDelayMs: number;
|
|
24
|
+
searchOptions: GoogleSearchAdvancedOptions;
|
|
25
|
+
}
|
|
26
|
+
export declare function parseSpiderSerpConfig(options: Record<string, unknown>): SpiderSerpOptionConfig;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getOptionValue, toOptionString, toNonNegativeInt, } from './option-helpers.js';
|
|
2
|
+
export const DEFAULT_SERP_KEYWORD_LIMIT = 5;
|
|
3
|
+
export const DEFAULT_SERP_MAX_RESULTS = 10;
|
|
4
|
+
export const DEFAULT_SERP_CONCURRENCY = 1;
|
|
5
|
+
export const DEFAULT_SERP_DELAY_MS = 1200;
|
|
6
|
+
export const DEFAULT_SERP_JITTER_MS = 450;
|
|
7
|
+
export const DEFAULT_SERP_CAPTCHA_COOLDOWN_MS = 2400;
|
|
8
|
+
export const DEFAULT_SERP_MAX_CONSECUTIVE_BLOCKS = 3;
|
|
9
|
+
export const DEFAULT_SERP_RETRY_COUNT = 1;
|
|
10
|
+
export const DEFAULT_SERP_RETRY_DELAY_MS = 1_200;
|
|
11
|
+
export const DEFAULT_SERP_HUMAN_PROFILE = 'chrome';
|
|
12
|
+
function toSearchTransport(value) {
|
|
13
|
+
const raw = toOptionString(value)?.toLowerCase();
|
|
14
|
+
if (raw === 'auto' || raw === 'undici' || raw === 'curl')
|
|
15
|
+
return raw;
|
|
16
|
+
return 'curl';
|
|
17
|
+
}
|
|
18
|
+
function toSerpSearchSource(value) {
|
|
19
|
+
const raw = toOptionString(value)?.toLowerCase();
|
|
20
|
+
return raw === 'google' ? 'google' : 'google';
|
|
21
|
+
}
|
|
22
|
+
function parseSerpExtraParams(value) {
|
|
23
|
+
const raw = toOptionString(value);
|
|
24
|
+
if (!raw)
|
|
25
|
+
return undefined;
|
|
26
|
+
const params = {};
|
|
27
|
+
const chunks = raw.includes('&')
|
|
28
|
+
? raw.split('&')
|
|
29
|
+
: raw.includes(';')
|
|
30
|
+
? raw.split(';')
|
|
31
|
+
: raw.split(',');
|
|
32
|
+
for (const chunk of chunks) {
|
|
33
|
+
const pair = chunk.trim();
|
|
34
|
+
if (!pair)
|
|
35
|
+
continue;
|
|
36
|
+
const idx = pair.indexOf('=');
|
|
37
|
+
if (idx <= 0)
|
|
38
|
+
continue;
|
|
39
|
+
const key = pair.slice(0, idx).trim();
|
|
40
|
+
const value = pair.slice(idx + 1).trim();
|
|
41
|
+
if (!key || !value)
|
|
42
|
+
continue;
|
|
43
|
+
if (/^(true|false)$/i.test(value)) {
|
|
44
|
+
params[key] = value.toLowerCase() === 'true';
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const numberValue = Number(value);
|
|
48
|
+
if (Number.isFinite(numberValue)) {
|
|
49
|
+
params[key] = numberValue;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
params[key] = value;
|
|
53
|
+
}
|
|
54
|
+
return Object.keys(params).length > 0 ? params : undefined;
|
|
55
|
+
}
|
|
56
|
+
function parseSerpHumanProfile(value) {
|
|
57
|
+
if (typeof value !== 'string') {
|
|
58
|
+
return DEFAULT_SERP_HUMAN_PROFILE;
|
|
59
|
+
}
|
|
60
|
+
const normalized = value.trim().toLowerCase();
|
|
61
|
+
if (!normalized || normalized === 'off' || normalized === 'false' || normalized === 'none' || normalized === '0') {
|
|
62
|
+
return 'off';
|
|
63
|
+
}
|
|
64
|
+
if (normalized === 'chrome' || normalized === 'browser' || normalized === 'human') {
|
|
65
|
+
return 'chrome';
|
|
66
|
+
}
|
|
67
|
+
if (normalized === 'default' || normalized === 'on' || normalized === 'true' || normalized === '1') {
|
|
68
|
+
return 'chrome';
|
|
69
|
+
}
|
|
70
|
+
return DEFAULT_SERP_HUMAN_PROFILE;
|
|
71
|
+
}
|
|
72
|
+
export function parseSpiderSerpConfig(options) {
|
|
73
|
+
const enabled = Boolean(getOptionValue(options, 'serp', 'serpEnabled'));
|
|
74
|
+
const topKeywordsLimit = toNonNegativeInt(getOptionValue(options, 'serpTopKeywords', 'serp-top-keywords'), DEFAULT_SERP_KEYWORD_LIMIT);
|
|
75
|
+
const queriesLimit = toNonNegativeInt(getOptionValue(options, 'serpQueryLimit', 'serp-query-limit'), DEFAULT_SERP_MAX_RESULTS);
|
|
76
|
+
const resultsPerQuery = toNonNegativeInt(getOptionValue(options, 'serpResultsPerQuery', 'serp-results-per-query'), DEFAULT_SERP_MAX_RESULTS);
|
|
77
|
+
const searchConcurrency = toNonNegativeInt(getOptionValue(options, 'serpConcurrency', 'serp-concurrency'), DEFAULT_SERP_CONCURRENCY);
|
|
78
|
+
const searchDelayMs = toNonNegativeInt(getOptionValue(options, 'serpDelayMs', 'serp-delay-ms', 'serpDelay'), DEFAULT_SERP_DELAY_MS);
|
|
79
|
+
const searchDelayJitterMs = toNonNegativeInt(getOptionValue(options, 'serpDelayJitterMs', 'serp-delay-jitter-ms', 'serpJitterMs'), DEFAULT_SERP_JITTER_MS);
|
|
80
|
+
const searchCaptchaCooldownMs = toNonNegativeInt(getOptionValue(options, 'serpCaptchaCooldownMs', 'serp-captcha-cooldown-ms', 'serpCaptchaCooldown'), DEFAULT_SERP_CAPTCHA_COOLDOWN_MS);
|
|
81
|
+
const searchMaxConsecutiveBlocks = toNonNegativeInt(getOptionValue(options, 'serpMaxConsecutiveBlocks', 'serp-max-consecutive-blocks'), DEFAULT_SERP_MAX_CONSECUTIVE_BLOCKS);
|
|
82
|
+
const searchRetryCount = toNonNegativeInt(getOptionValue(options, 'serpRetryCount', 'serp-retry-count', 'serpRetries'), DEFAULT_SERP_RETRY_COUNT);
|
|
83
|
+
const searchRetryDelayMs = toNonNegativeInt(getOptionValue(options, 'serpRetryDelayMs', 'serp-retry-delay-ms', 'serpRetryDelay'), DEFAULT_SERP_RETRY_DELAY_MS);
|
|
84
|
+
const searchSource = toSerpSearchSource(getOptionValue(options, 'serpSource', 'serp-source'));
|
|
85
|
+
const country = getOptionValue(options, 'serpCountry', 'serp-country', 'serpRegion', 'serp-region');
|
|
86
|
+
return {
|
|
87
|
+
enabled,
|
|
88
|
+
topKeywordsLimit: topKeywordsLimit > 0 ? topKeywordsLimit : DEFAULT_SERP_KEYWORD_LIMIT,
|
|
89
|
+
queriesLimit: queriesLimit > 0 ? queriesLimit : DEFAULT_SERP_MAX_RESULTS,
|
|
90
|
+
resultsPerQuery: resultsPerQuery > 0 ? resultsPerQuery : DEFAULT_SERP_MAX_RESULTS,
|
|
91
|
+
searchConcurrency: searchConcurrency > 0 ? searchConcurrency : DEFAULT_SERP_CONCURRENCY,
|
|
92
|
+
searchDelayMs: searchDelayMs > 0 ? searchDelayMs : DEFAULT_SERP_DELAY_MS,
|
|
93
|
+
searchDelayJitterMs: searchDelayJitterMs > 0 ? searchDelayJitterMs : DEFAULT_SERP_JITTER_MS,
|
|
94
|
+
searchCaptchaCooldownMs: searchCaptchaCooldownMs > 0 ? searchCaptchaCooldownMs : DEFAULT_SERP_CAPTCHA_COOLDOWN_MS,
|
|
95
|
+
searchMaxConsecutiveBlocks: searchMaxConsecutiveBlocks >= 0
|
|
96
|
+
? searchMaxConsecutiveBlocks
|
|
97
|
+
: DEFAULT_SERP_MAX_CONSECUTIVE_BLOCKS,
|
|
98
|
+
searchRetryCount: searchRetryCount >= 0 ? searchRetryCount : DEFAULT_SERP_RETRY_COUNT,
|
|
99
|
+
searchRetryDelayMs: searchRetryDelayMs > 0 ? searchRetryDelayMs : DEFAULT_SERP_RETRY_DELAY_MS,
|
|
100
|
+
searchOptions: {
|
|
101
|
+
transport: toSearchTransport(getOptionValue(options, 'serpTransport', 'serp-transport')),
|
|
102
|
+
source: searchSource,
|
|
103
|
+
timeout: toNonNegativeInt(getOptionValue(options, 'serpTimeout', 'serp-timeout'), 0) || undefined,
|
|
104
|
+
country: toOptionString(country),
|
|
105
|
+
gl: toOptionString(getOptionValue(options, 'serpGl', 'serp-gl')),
|
|
106
|
+
hl: toOptionString(getOptionValue(options, 'serpHl', 'serp-hl')),
|
|
107
|
+
safe: toOptionString(getOptionValue(options, 'serpSafe', 'serp-safe')),
|
|
108
|
+
as_q: toOptionString(getOptionValue(options, 'serpAsQ', 'serp-as-q')),
|
|
109
|
+
as_epq: toOptionString(getOptionValue(options, 'serpAsEpq', 'serp-as-epq', 'serpAsEpq')),
|
|
110
|
+
as_oq: toOptionString(getOptionValue(options, 'serpAsOq', 'serp-as-oq')),
|
|
111
|
+
as_eq: toOptionString(getOptionValue(options, 'serpAsEq', 'serp-as-eq')),
|
|
112
|
+
as_sitesearch: toOptionString(getOptionValue(options, 'serpAsSitesearch', 'serp-as-sitesearch', 'serpAsSitesearch')),
|
|
113
|
+
as_filetype: toOptionString(getOptionValue(options, 'serpAsFiletype', 'serp-as-filetype', 'serpAsFiletype')),
|
|
114
|
+
as_rights: toOptionString(getOptionValue(options, 'serpAsRights', 'serp-as-rights', 'serpAsRights')),
|
|
115
|
+
as_nlo: toOptionString(getOptionValue(options, 'serpAsNlo', 'serp-as-nlo', 'serpNlo')),
|
|
116
|
+
as_nhi: toOptionString(getOptionValue(options, 'serpAsNhi', 'serp-as-nhi', 'serpNhi')),
|
|
117
|
+
humanProfile: parseSerpHumanProfile(getOptionValue(options, 'serpHumanProfile', 'serp-human-profile')),
|
|
118
|
+
lr: toOptionString(getOptionValue(options, 'serpLr', 'serp-lr')),
|
|
119
|
+
cr: toOptionString(getOptionValue(options, 'serpCr', 'serp-cr')),
|
|
120
|
+
tbs: toOptionString(getOptionValue(options, 'serpTbs', 'serp-tbs')),
|
|
121
|
+
tbm: toOptionString(getOptionValue(options, 'serpTbm', 'serp-tbm')),
|
|
122
|
+
extraParams: parseSerpExtraParams(getOptionValue(options, 'serpExtra', 'serp-extra')),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
package/dist/core/client.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ interface BatchRequestOptions<T = ReckerResponse> {
|
|
|
22
22
|
signal?: AbortSignal;
|
|
23
23
|
deadlineMs?: number;
|
|
24
24
|
}
|
|
25
|
+
type RequestWithBodyOptions = Omit<RequestOptions, 'method'>;
|
|
25
26
|
export interface ExtendedClientOptions extends ClientOptions {
|
|
26
27
|
retry?: RetryOptions;
|
|
27
28
|
cache?: ClientCacheConfig;
|
|
@@ -36,6 +37,7 @@ export declare class Client {
|
|
|
36
37
|
private hooks;
|
|
37
38
|
private transport;
|
|
38
39
|
private curlTransport?;
|
|
40
|
+
private proxyConfig?;
|
|
39
41
|
private defaultHeaders;
|
|
40
42
|
private defaultHeadersObj;
|
|
41
43
|
private defaultParams;
|
|
@@ -104,28 +106,31 @@ export declare class Client {
|
|
|
104
106
|
};
|
|
105
107
|
}>;
|
|
106
108
|
private requestWithBody;
|
|
107
|
-
post<T = unknown>(path: string,
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
post<T = unknown>(path: string, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
110
|
+
post<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
111
|
+
put<T = unknown>(path: string, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
112
|
+
put<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
113
|
+
patch<T = unknown>(path: string, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
114
|
+
patch<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
110
115
|
delete<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
111
116
|
head<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
112
117
|
options<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
113
118
|
trace<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
114
119
|
connect<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
115
120
|
purge<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
116
|
-
propfind<T = unknown>(path: string, body?:
|
|
117
|
-
proppatch<T = unknown>(path: string, body?:
|
|
121
|
+
propfind<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
122
|
+
proppatch<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
118
123
|
mkcol<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
119
124
|
copy<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
120
125
|
move<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
121
|
-
lock<T = unknown>(path: string, body?:
|
|
126
|
+
lock<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
122
127
|
unlock<T = unknown>(path: string, options?: Omit<RequestOptions, 'method'>): RequestPromise<T>;
|
|
123
|
-
link<T = unknown>(path: string, body?:
|
|
124
|
-
unlink<T = unknown>(path: string, body?:
|
|
128
|
+
link<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
129
|
+
unlink<T = unknown>(path: string, body?: unknown, options?: RequestWithBodyOptions): RequestPromise<T>;
|
|
125
130
|
scrape(path: string, options?: RequestOptions): ScrapePromise<ReckerResponse>;
|
|
126
131
|
paginate<T>(path: string, options?: RequestOptions & PaginationOptions<T>): AsyncGenerator<T>;
|
|
127
|
-
pages<T =
|
|
128
|
-
page<T =
|
|
132
|
+
pages<T = unknown>(path: string, options?: RequestOptions & PaginationOptions): AsyncGenerator<PageResult<T>>;
|
|
133
|
+
page<T = unknown>(path: string, pageNumber: number, options?: RequestOptions & {
|
|
129
134
|
pageParam?: string;
|
|
130
135
|
}): RequestPromise<T>;
|
|
131
136
|
getAll<T>(path: string, options?: RequestOptions & PaginationOptions<T>): Promise<T[]>;
|
package/dist/core/client.js
CHANGED
|
@@ -28,8 +28,34 @@ import { ReckerWebSocket } from '../websocket/client.js';
|
|
|
28
28
|
import { whois as performWhois, isDomainAvailable } from '../utils/whois.js';
|
|
29
29
|
import { MemoryCookieJar } from '../cookies/memory-cookie-jar.js';
|
|
30
30
|
import { scrape as scrapeHelper } from '../plugins/scrape.js';
|
|
31
|
+
const toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
32
|
+
const BODY_OPTION_HINTS = [
|
|
33
|
+
'json',
|
|
34
|
+
'form',
|
|
35
|
+
'xml',
|
|
36
|
+
'yaml',
|
|
37
|
+
'csv',
|
|
38
|
+
'body',
|
|
39
|
+
'headers',
|
|
40
|
+
'timeout',
|
|
41
|
+
'retry',
|
|
42
|
+
'hooks',
|
|
43
|
+
'searchParams',
|
|
44
|
+
'params',
|
|
45
|
+
'beforeRedirect',
|
|
46
|
+
'maxRedirects',
|
|
47
|
+
'followRedirects',
|
|
48
|
+
'http2',
|
|
49
|
+
'useCurl',
|
|
50
|
+
];
|
|
31
51
|
function isNodeRuntime() {
|
|
32
|
-
|
|
52
|
+
const maybeNodeGlobal = globalThis;
|
|
53
|
+
return typeof globalThis !== 'undefined' && Boolean(maybeNodeGlobal.process?.versions?.node);
|
|
54
|
+
}
|
|
55
|
+
function isRequestWithBodyOptions(value) {
|
|
56
|
+
if (!isPlainObject(value))
|
|
57
|
+
return false;
|
|
58
|
+
return BODY_OPTION_HINTS.some((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
33
59
|
}
|
|
34
60
|
class LazyTransport {
|
|
35
61
|
factory;
|
|
@@ -67,7 +93,7 @@ class LazyTransport {
|
|
|
67
93
|
await this.resolving;
|
|
68
94
|
}
|
|
69
95
|
}
|
|
70
|
-
function createLazyCurlTransport() {
|
|
96
|
+
function createLazyCurlTransport(proxy) {
|
|
71
97
|
if (!isNodeRuntime()) {
|
|
72
98
|
return {
|
|
73
99
|
async dispatch(req) {
|
|
@@ -77,7 +103,7 @@ function createLazyCurlTransport() {
|
|
|
77
103
|
}
|
|
78
104
|
return new LazyTransport(async () => {
|
|
79
105
|
const { CurlTransport } = await import('../transport/curl.js');
|
|
80
|
-
return new CurlTransport();
|
|
106
|
+
return new CurlTransport(proxy);
|
|
81
107
|
});
|
|
82
108
|
}
|
|
83
109
|
class LazyCacheStorage {
|
|
@@ -179,6 +205,7 @@ export class Client {
|
|
|
179
205
|
hooks;
|
|
180
206
|
transport;
|
|
181
207
|
curlTransport;
|
|
208
|
+
proxyConfig;
|
|
182
209
|
defaultHeaders;
|
|
183
210
|
defaultHeadersObj;
|
|
184
211
|
defaultParams;
|
|
@@ -222,6 +249,7 @@ export class Client {
|
|
|
222
249
|
this.defaultParams = options.defaults?.params || {};
|
|
223
250
|
this.paginationConfig = options.pagination;
|
|
224
251
|
this.maxResponseSize = options.maxResponseSize;
|
|
252
|
+
this.proxyConfig = options.proxy;
|
|
225
253
|
const runtimeEventBus = options.runtimeEventBus;
|
|
226
254
|
if (runtimeEventBus) {
|
|
227
255
|
this.runtimeEventBus = {
|
|
@@ -254,7 +282,7 @@ export class Client {
|
|
|
254
282
|
else if (options.useCurl) {
|
|
255
283
|
if (this.debugEnabled)
|
|
256
284
|
console.log('[DEBUG] Using Curl Transport');
|
|
257
|
-
this.transport = createLazyCurlTransport();
|
|
285
|
+
this.transport = createLazyCurlTransport(options.proxy);
|
|
258
286
|
this.transportKind = 'curl';
|
|
259
287
|
}
|
|
260
288
|
else if (isNodeRuntime()) {
|
|
@@ -290,8 +318,9 @@ export class Client {
|
|
|
290
318
|
this.transportKind = 'undici';
|
|
291
319
|
}
|
|
292
320
|
else {
|
|
293
|
-
if (this.debugEnabled)
|
|
294
|
-
|
|
321
|
+
if (this.debugEnabled && this.logger) {
|
|
322
|
+
this.logger.debug('Using Fetch Transport');
|
|
323
|
+
}
|
|
295
324
|
this.transport = new FetchTransport();
|
|
296
325
|
this.transportKind = 'fetch';
|
|
297
326
|
}
|
|
@@ -317,7 +346,8 @@ export class Client {
|
|
|
317
346
|
interval: this.concurrencyConfig.interval
|
|
318
347
|
});
|
|
319
348
|
registerPlugin((client) => {
|
|
320
|
-
client
|
|
349
|
+
const pluginClient = client;
|
|
350
|
+
pluginClient.middlewares?.unshift(this.requestPool.asMiddleware());
|
|
321
351
|
}, {
|
|
322
352
|
name: 'recker:request-pool',
|
|
323
353
|
priority: 130,
|
|
@@ -525,7 +555,7 @@ export class Client {
|
|
|
525
555
|
try {
|
|
526
556
|
if (req.useCurl && this.transportKind !== 'curl') {
|
|
527
557
|
if (!this.curlTransport) {
|
|
528
|
-
this.curlTransport = createLazyCurlTransport();
|
|
558
|
+
this.curlTransport = createLazyCurlTransport(this.proxyConfig);
|
|
529
559
|
}
|
|
530
560
|
const response = await this.curlTransport.dispatch(req);
|
|
531
561
|
if (context) {
|
|
@@ -552,7 +582,7 @@ export class Client {
|
|
|
552
582
|
this.runtimeEventBus.emit('transport:error', {
|
|
553
583
|
context,
|
|
554
584
|
req,
|
|
555
|
-
error:
|
|
585
|
+
error: toError(error)
|
|
556
586
|
});
|
|
557
587
|
}
|
|
558
588
|
throw error;
|
|
@@ -768,7 +798,7 @@ export class Client {
|
|
|
768
798
|
});
|
|
769
799
|
return response;
|
|
770
800
|
}, (error) => {
|
|
771
|
-
const requestError =
|
|
801
|
+
const requestError = toError(error);
|
|
772
802
|
this.runtimeEventBus.emit('request:failed', {
|
|
773
803
|
context: requestContext,
|
|
774
804
|
req,
|
|
@@ -849,7 +879,7 @@ export class Client {
|
|
|
849
879
|
});
|
|
850
880
|
return response;
|
|
851
881
|
}, (error) => {
|
|
852
|
-
const requestError =
|
|
882
|
+
const requestError = toError(error);
|
|
853
883
|
this.runtimeEventBus.emit('request:failed', {
|
|
854
884
|
context: requestContext,
|
|
855
885
|
req,
|
|
@@ -873,8 +903,9 @@ export class Client {
|
|
|
873
903
|
return this.request(path, { ...options, method: 'GET' });
|
|
874
904
|
}
|
|
875
905
|
async warmup() {
|
|
876
|
-
|
|
877
|
-
|
|
906
|
+
const transport = this.transport;
|
|
907
|
+
if (transport?.warmup) {
|
|
908
|
+
await transport.warmup();
|
|
878
909
|
}
|
|
879
910
|
}
|
|
880
911
|
async batch(requests, options = {}) {
|
|
@@ -899,29 +930,14 @@ export class Client {
|
|
|
899
930
|
}
|
|
900
931
|
requestWithBody(method, path, bodyOrOptions, options) {
|
|
901
932
|
let actualBody = bodyOrOptions;
|
|
902
|
-
let actualOptions = options;
|
|
903
|
-
const isOptionsEmpty =
|
|
904
|
-
(
|
|
905
|
-
if (isOptionsEmpty &&
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
potentialOptions.yaml !== undefined ||
|
|
911
|
-
potentialOptions.csv !== undefined ||
|
|
912
|
-
potentialOptions.body !== undefined ||
|
|
913
|
-
potentialOptions.headers !== undefined ||
|
|
914
|
-
potentialOptions.timeout !== undefined ||
|
|
915
|
-
potentialOptions.retry !== undefined ||
|
|
916
|
-
potentialOptions.hooks !== undefined ||
|
|
917
|
-
potentialOptions.searchParams !== undefined ||
|
|
918
|
-
potentialOptions.params !== undefined) {
|
|
919
|
-
actualOptions = bodyOrOptions;
|
|
920
|
-
actualBody = undefined;
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
actualOptions = actualOptions || {};
|
|
924
|
-
const { json, form, xml, yaml, csv, ...restOptions } = actualOptions;
|
|
933
|
+
let actualOptions = options || {};
|
|
934
|
+
const isOptionsEmpty = options === undefined
|
|
935
|
+
|| (isPlainObject(options) && Object.keys(options).length === 0);
|
|
936
|
+
if (isOptionsEmpty && isRequestWithBodyOptions(bodyOrOptions)) {
|
|
937
|
+
actualOptions = bodyOrOptions;
|
|
938
|
+
actualBody = undefined;
|
|
939
|
+
}
|
|
940
|
+
const { json, form, xml, yaml, csv, body: explicitBody, ...restOptions } = actualOptions;
|
|
925
941
|
let finalBody = actualBody;
|
|
926
942
|
let explicitContentType;
|
|
927
943
|
if (form !== undefined) {
|
|
@@ -944,8 +960,8 @@ export class Client {
|
|
|
944
960
|
finalBody = serializeCsv(csv);
|
|
945
961
|
explicitContentType = 'text/csv';
|
|
946
962
|
}
|
|
947
|
-
else if (
|
|
948
|
-
finalBody =
|
|
963
|
+
else if (explicitBody !== undefined) {
|
|
964
|
+
finalBody = explicitBody;
|
|
949
965
|
}
|
|
950
966
|
const { body: processedBody, contentType } = processBody(finalBody);
|
|
951
967
|
const headers = new Headers(restOptions.headers);
|
package/dist/index.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * from './utils/concurrency.js';
|
|
|
74
74
|
export * as presets from './presets/index.js';
|
|
75
75
|
export * as testing from './testing/index.js';
|
|
76
76
|
export * as protocols from './protocols/index.js';
|
|
77
|
+
export * from './raffel/index.js';
|
|
77
78
|
export * from './mcp/client.js';
|
|
78
79
|
export * from './mcp/contract.js';
|
|
79
80
|
export * as template from './template/index.js';
|
package/dist/index.js
CHANGED
|
@@ -74,6 +74,7 @@ export * from './utils/concurrency.js';
|
|
|
74
74
|
export * as presets from './presets/index.js';
|
|
75
75
|
export * as testing from './testing/index.js';
|
|
76
76
|
export * as protocols from './protocols/index.js';
|
|
77
|
+
export * from './raffel/index.js';
|
|
77
78
|
export * from './mcp/client.js';
|
|
78
79
|
export * from './mcp/contract.js';
|
|
79
80
|
export * as template from './template/index.js';
|
package/dist/mcp/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { RekCommand as Command } from '../cli/router.js';
|
|
|
3
3
|
import { MCPServer } from './server.js';
|
|
4
4
|
import { listCategories, DEFAULT_CATEGORY, validateCategories, estimateCategoryTokens, } from './profiles.js';
|
|
5
5
|
import { LEGACY_TOOL_GROUPS } from './legacy-tool-groups.js';
|
|
6
|
+
import { consoleLogger } from '../types/logger.js';
|
|
6
7
|
const program = new Command('recker-mcp');
|
|
7
8
|
program
|
|
8
9
|
.description('Start the Recker MCP server for AI agent integration')
|
|
@@ -29,25 +30,25 @@ program
|
|
|
29
30
|
opts.transport = opts.transport || 'stdio';
|
|
30
31
|
opts.port = opts.port || '3100';
|
|
31
32
|
if (opts.listCategories) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
consoleLogger.info('╔═══════════════════════════════════════════════════════════════════╗');
|
|
34
|
+
consoleLogger.info('║ Recker MCP Categories ║');
|
|
35
|
+
consoleLogger.info('╚═══════════════════════════════════════════════════════════════════╝');
|
|
36
|
+
consoleLogger.info('');
|
|
37
|
+
consoleLogger.info('Available categories:');
|
|
38
|
+
consoleLogger.info('');
|
|
38
39
|
for (const category of listCategories()) {
|
|
39
40
|
const toolCount = category.toolCount === -1 ? 'all' : category.toolCount;
|
|
40
41
|
const icon = category.icon || '📦';
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
consoleLogger.info(` ${icon} ${category.name.padEnd(12)} ${category.description}`);
|
|
43
|
+
consoleLogger.info(` Tools: ${toolCount}, ~${category.estimatedTokens} tokens`);
|
|
44
|
+
consoleLogger.info('');
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
consoleLogger.info('Usage examples:');
|
|
47
|
+
consoleLogger.info(' recker-mcp # Default: minimal category');
|
|
48
|
+
consoleLogger.info(' recker-mcp --category=minimal,seo # Combine categories');
|
|
49
|
+
consoleLogger.info(' recker-mcp -c seo,security # Short form');
|
|
50
|
+
consoleLogger.info(' recker-mcp --category=full # All tools (high context)');
|
|
51
|
+
consoleLogger.info('');
|
|
51
52
|
process.exit(0);
|
|
52
53
|
}
|
|
53
54
|
const useExplicitCategory = Boolean(opts.category);
|
|
@@ -55,8 +56,8 @@ program
|
|
|
55
56
|
const categoryNames = opts.category.split(',').map((p) => p.trim());
|
|
56
57
|
const validation = validateCategories(categoryNames);
|
|
57
58
|
if (!validation.valid) {
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
consoleLogger.error(`Invalid category(s): ${validation.invalid.join(', ')}`);
|
|
60
|
+
consoleLogger.error('Use --list-categories to see available categories');
|
|
60
61
|
process.exit(1);
|
|
61
62
|
}
|
|
62
63
|
}
|
|
@@ -97,7 +98,7 @@ program
|
|
|
97
98
|
const transport = opts.transport;
|
|
98
99
|
const port = parseInt(opts.port, 10);
|
|
99
100
|
if (!['stdio', 'http', 'sse'].includes(transport)) {
|
|
100
|
-
|
|
101
|
+
consoleLogger.error(`Invalid transport mode: ${transport}. Use: stdio, http, or sse`);
|
|
101
102
|
process.exit(1);
|
|
102
103
|
}
|
|
103
104
|
const effectiveCategory = useExplicitCategory ? opts.category : (!opts.only && !opts.filter ? DEFAULT_CATEGORY : undefined);
|
|
@@ -112,25 +113,25 @@ program
|
|
|
112
113
|
toolsFilter: !effectiveCategory && toolsFilter.length > 0 ? toolsFilter : undefined,
|
|
113
114
|
});
|
|
114
115
|
if (transport !== 'stdio') {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
consoleLogger.info('╔═══════════════════════════════════════════════════════════════════╗');
|
|
117
|
+
consoleLogger.info('║ Recker MCP Server ║');
|
|
118
|
+
consoleLogger.info('╚═══════════════════════════════════════════════════════════════════╝');
|
|
119
|
+
consoleLogger.info('');
|
|
120
|
+
consoleLogger.info(` Transport: ${transport}`);
|
|
121
|
+
consoleLogger.info(` Port: ${port}`);
|
|
122
|
+
consoleLogger.info(` Debug: ${opts.debug ? 'enabled' : 'disabled'}`);
|
|
122
123
|
if (effectiveCategory) {
|
|
123
124
|
const tokens = estimateCategoryTokens(effectiveCategory);
|
|
124
|
-
|
|
125
|
+
consoleLogger.info(` Category: ${effectiveCategory} (~${tokens} tokens)`);
|
|
125
126
|
}
|
|
126
127
|
else if (toolsFilter.length > 0) {
|
|
127
|
-
|
|
128
|
+
consoleLogger.info(` Filters: ${toolsFilter.join(', ')}`);
|
|
128
129
|
}
|
|
129
130
|
else {
|
|
130
|
-
|
|
131
|
+
consoleLogger.info(' Category: minimal (default)');
|
|
131
132
|
}
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
consoleLogger.info('');
|
|
134
|
+
consoleLogger.info(' Available tools:');
|
|
134
135
|
const allTools = [
|
|
135
136
|
...LEGACY_TOOL_GROUPS.docs,
|
|
136
137
|
...LEGACY_TOOL_GROUPS.network,
|
|
@@ -148,15 +149,15 @@ program
|
|
|
148
149
|
return positive.includes(tool);
|
|
149
150
|
});
|
|
150
151
|
enabledTools.forEach(tool => {
|
|
151
|
-
|
|
152
|
+
consoleLogger.info(` ✓ ${tool}`);
|
|
152
153
|
});
|
|
153
154
|
const disabledTools = allTools.filter(t => !enabledTools.includes(t));
|
|
154
155
|
if (disabledTools.length > 0) {
|
|
155
|
-
disabledTools.forEach(tool => {
|
|
156
|
-
|
|
156
|
+
disabledTools.forEach((tool) => {
|
|
157
|
+
consoleLogger.info(` ✗ ${tool} (disabled)`);
|
|
157
158
|
});
|
|
158
159
|
}
|
|
159
|
-
|
|
160
|
+
consoleLogger.info('');
|
|
160
161
|
}
|
|
161
162
|
await server.start();
|
|
162
163
|
});
|
package/dist/mcp/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import type { MCPServerInfo, MCPTool, MCPToolResult, MCPResource, MCPResourceContent, MCPPrompt, MCPPromptMessage } from './types.js';
|
|
2
|
+
import type { MCPServerInfo, MCPTool, MCPToolResult, MCPResource, MCPResourceContent, MCPPrompt, MCPPromptMessage, MCPTransportOptions } from './types.js';
|
|
3
3
|
export interface MCPClientOptions {
|
|
4
4
|
endpoint: string;
|
|
5
5
|
clientName?: string;
|
|
@@ -9,7 +9,7 @@ export interface MCPClientOptions {
|
|
|
9
9
|
timeout?: number;
|
|
10
10
|
retries?: number;
|
|
11
11
|
debug?: boolean;
|
|
12
|
-
transport?:
|
|
12
|
+
transport?: MCPTransportOptions['transport'];
|
|
13
13
|
}
|
|
14
14
|
interface ResolvedMCPClientOptions {
|
|
15
15
|
endpoint: string;
|