recker 1.0.40 → 1.0.41-next.2e33802
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/cli/index.js +1 -1
- package/dist/cli/tui/shell-search.js +2 -2
- package/dist/mcp/prompts/index.d.ts +16 -0
- package/dist/mcp/prompts/index.js +115 -0
- package/dist/mcp/search/types.d.ts +1 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +22 -3
- package/dist/mcp/tools/seo.js +10 -21
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -4619,7 +4619,7 @@ ${colors.bold(colors.yellow('Tools provided:'))}
|
|
|
4619
4619
|
${colors.bold(colors.yellow('Claude Code config (~/.claude.json):'))}
|
|
4620
4620
|
${colors.gray(`{
|
|
4621
4621
|
"mcpServers": {
|
|
4622
|
-
"recker
|
|
4622
|
+
"recker": {
|
|
4623
4623
|
"command": "npx",
|
|
4624
4624
|
"args": ["recker", "mcp"]
|
|
4625
4625
|
}
|
|
@@ -293,8 +293,8 @@ const { results, stats } = await client.batch([
|
|
|
293
293
|
const data = await loadEmbeddings({ debug: false });
|
|
294
294
|
if (data && data.documents && data.documents.length > 0) {
|
|
295
295
|
for (const doc of data.documents) {
|
|
296
|
-
let content = '';
|
|
297
|
-
if (!doc.section) {
|
|
296
|
+
let content = doc.content || '';
|
|
297
|
+
if (!content && !doc.section) {
|
|
298
298
|
const fullPath = join(this.docsPath, doc.path);
|
|
299
299
|
if (existsSync(fullPath)) {
|
|
300
300
|
content = readFileSync(fullPath, 'utf-8');
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MCPPrompt, MCPPromptMessage } from '../types.js';
|
|
2
|
+
export interface PromptHandler {
|
|
3
|
+
(args?: Record<string, string>): Promise<MCPPromptMessage[]> | MCPPromptMessage[];
|
|
4
|
+
}
|
|
5
|
+
export interface RegisteredPrompt {
|
|
6
|
+
definition: MCPPrompt;
|
|
7
|
+
handler: PromptHandler;
|
|
8
|
+
}
|
|
9
|
+
export declare class PromptRegistry {
|
|
10
|
+
private prompts;
|
|
11
|
+
constructor();
|
|
12
|
+
registerPrompt(definition: MCPPrompt, handler: PromptHandler): void;
|
|
13
|
+
listPrompts(): MCPPrompt[];
|
|
14
|
+
getPrompt(name: string, args?: Record<string, string>): Promise<MCPPromptMessage[]>;
|
|
15
|
+
private registerBuiltInPrompts;
|
|
16
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export class PromptRegistry {
|
|
2
|
+
prompts = new Map();
|
|
3
|
+
constructor() {
|
|
4
|
+
this.registerBuiltInPrompts();
|
|
5
|
+
}
|
|
6
|
+
registerPrompt(definition, handler) {
|
|
7
|
+
this.prompts.set(definition.name, { definition, handler });
|
|
8
|
+
}
|
|
9
|
+
listPrompts() {
|
|
10
|
+
return Array.from(this.prompts.values()).map(p => p.definition);
|
|
11
|
+
}
|
|
12
|
+
async getPrompt(name, args) {
|
|
13
|
+
const prompt = this.prompts.get(name);
|
|
14
|
+
if (!prompt) {
|
|
15
|
+
throw new Error(`Prompt not found: ${name}`);
|
|
16
|
+
}
|
|
17
|
+
return prompt.handler(args);
|
|
18
|
+
}
|
|
19
|
+
registerBuiltInPrompts() {
|
|
20
|
+
this.registerPrompt({
|
|
21
|
+
name: 'recker-expert',
|
|
22
|
+
description: 'Instructs the AI to act as a Recker SDK expert, focusing on best practices and idiomatic usage.',
|
|
23
|
+
}, () => [{
|
|
24
|
+
role: 'user',
|
|
25
|
+
content: {
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: `You are an expert in Recker, the AI & DevX focused Network SDK for Node.js.
|
|
28
|
+
Your goal is to help developers build robust, efficient, and AI-powered network applications.
|
|
29
|
+
|
|
30
|
+
Key Principles of Recker:
|
|
31
|
+
1. **Zero-Config Defaults**: Prefer 'await recker.get()' over complex setup.
|
|
32
|
+
2. **Unified API**: Use the same client for HTTP, DNS, WHOIS, and AI interactions.
|
|
33
|
+
3. **Resilience**: Always suggest adding retries and circuit breakers for production code.
|
|
34
|
+
4. **AI-Native**: Highlight features like 'stream().sse()' and 'recker.ai' when relevant.
|
|
35
|
+
5. **Type Safety**: Emphasize Recker's strong TypeScript support.
|
|
36
|
+
|
|
37
|
+
When providing code examples:
|
|
38
|
+
- Use TypeScript.
|
|
39
|
+
- Use 'import { recker, createClient } from "recker";'.
|
|
40
|
+
- Prefer the functional API ('recker.get') for simple tasks.
|
|
41
|
+
- Suggest 'createClient' for reusable configurations.
|
|
42
|
+
- Use plugins (retry, cache, dedup) to solve reliability issues.`
|
|
43
|
+
}
|
|
44
|
+
}]);
|
|
45
|
+
this.registerPrompt({
|
|
46
|
+
name: 'generate-http-client',
|
|
47
|
+
description: 'Generates a robust Recker client configuration for a specific API.',
|
|
48
|
+
arguments: [
|
|
49
|
+
{
|
|
50
|
+
name: 'apiName',
|
|
51
|
+
description: 'Name of the API (e.g., "GitHub API", "Stripe")',
|
|
52
|
+
required: true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'baseUrl',
|
|
56
|
+
description: 'Base URL of the API',
|
|
57
|
+
required: true
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'authType',
|
|
61
|
+
description: 'Authentication type (bearer, basic, api-key)',
|
|
62
|
+
required: false
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}, (args) => {
|
|
66
|
+
const { apiName, baseUrl, authType = 'bearer' } = args || {};
|
|
67
|
+
return [{
|
|
68
|
+
role: 'user',
|
|
69
|
+
content: {
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: `Generate a production-ready Recker client configuration for the ${apiName}.
|
|
72
|
+
|
|
73
|
+
Target API: ${baseUrl}
|
|
74
|
+
Auth Type: ${authType}
|
|
75
|
+
|
|
76
|
+
Requirements:
|
|
77
|
+
1. Use 'createClient'.
|
|
78
|
+
2. Configure sensible defaults for retries (exponential backoff) and timeouts.
|
|
79
|
+
3. Add a rate-limiting plugin if appropriate for this type of API.
|
|
80
|
+
4. Include an example of how to use this client to make a request.
|
|
81
|
+
5. If the API requires authentication, show how to inject the token securely (e.g., from process.env).`
|
|
82
|
+
}
|
|
83
|
+
}];
|
|
84
|
+
});
|
|
85
|
+
this.registerPrompt({
|
|
86
|
+
name: 'seo-audit',
|
|
87
|
+
description: 'Guides the AI to perform a comprehensive SEO audit using Recker tools.',
|
|
88
|
+
arguments: [
|
|
89
|
+
{
|
|
90
|
+
name: 'url',
|
|
91
|
+
description: 'The URL to audit',
|
|
92
|
+
required: true
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}, (args) => {
|
|
96
|
+
const { url } = args || {};
|
|
97
|
+
return [{
|
|
98
|
+
role: 'user',
|
|
99
|
+
content: {
|
|
100
|
+
type: 'text',
|
|
101
|
+
text: `I need to perform a comprehensive SEO audit for ${url}.
|
|
102
|
+
|
|
103
|
+
Please use Recker's MCP tools to analyze the site. Follow this plan:
|
|
104
|
+
|
|
105
|
+
1. **Initial Assessment**: Use 'rek_seo_analyze' to check the homepage for critical meta tag, structure, and performance issues.
|
|
106
|
+
2. **Security Check**: Use 'rek_security_headers' and 'rek_tls_inspect' to ensure the site is secure and trusted.
|
|
107
|
+
3. **Crawl**: Use 'rek_seo_spider' (limit to 20 pages) to identify broken links, duplicate content, or orphan pages.
|
|
108
|
+
4. **Quick Wins**: Use 'rek_seo_quick_wins' to identify the high-impact, low-effort fixes.
|
|
109
|
+
|
|
110
|
+
After running these tools, analyze the results and provide a prioritized action plan for improving the site's SEO.`
|
|
111
|
+
}
|
|
112
|
+
}];
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
package/dist/mcp/server.d.ts
CHANGED
package/dist/mcp/server.js
CHANGED
|
@@ -13,6 +13,7 @@ import { scrapeTools, scrapeToolHandlers } from './tools/scrape.js';
|
|
|
13
13
|
import { securityTools, securityToolHandlers } from './tools/security.js';
|
|
14
14
|
import { ToolRegistry } from './tools/registry.js';
|
|
15
15
|
import { loadToolModules } from './tools/loader.js';
|
|
16
|
+
import { PromptRegistry } from './prompts/index.js';
|
|
16
17
|
export class MCPServer {
|
|
17
18
|
options;
|
|
18
19
|
server;
|
|
@@ -23,10 +24,11 @@ export class MCPServer {
|
|
|
23
24
|
sseClients = new Set();
|
|
24
25
|
initialized = false;
|
|
25
26
|
toolRegistry;
|
|
27
|
+
promptRegistry;
|
|
26
28
|
aiClient;
|
|
27
29
|
constructor(options = {}) {
|
|
28
30
|
this.options = {
|
|
29
|
-
name: options.name || 'recker
|
|
31
|
+
name: options.name || 'recker',
|
|
30
32
|
version: options.version || '1.0.0',
|
|
31
33
|
docsPath: options.docsPath || this.findDocsPath(),
|
|
32
34
|
examplesPath: options.examplesPath || this.findExamplesPath(),
|
|
@@ -43,6 +45,7 @@ export class MCPServer {
|
|
|
43
45
|
embedder: (text, model) => this.generateEmbedding(text, model || 'BGESmallENV15'),
|
|
44
46
|
});
|
|
45
47
|
this.toolRegistry = new ToolRegistry();
|
|
48
|
+
this.promptRegistry = new PromptRegistry();
|
|
46
49
|
this.registerInternalTools();
|
|
47
50
|
this.toolRegistry.registerModule({
|
|
48
51
|
tools: networkTools,
|
|
@@ -1150,8 +1153,24 @@ const client = createClient({
|
|
|
1150
1153
|
};
|
|
1151
1154
|
}
|
|
1152
1155
|
}
|
|
1153
|
-
case 'prompts/list':
|
|
1154
|
-
|
|
1156
|
+
case 'prompts/list': {
|
|
1157
|
+
const prompts = this.promptRegistry.listPrompts();
|
|
1158
|
+
return { jsonrpc: '2.0', id: id, result: { prompts } };
|
|
1159
|
+
}
|
|
1160
|
+
case 'prompts/get': {
|
|
1161
|
+
const { name, arguments: args } = params;
|
|
1162
|
+
try {
|
|
1163
|
+
const messages = await this.promptRegistry.getPrompt(name, args);
|
|
1164
|
+
return { jsonrpc: '2.0', id: id, result: { messages } };
|
|
1165
|
+
}
|
|
1166
|
+
catch (error) {
|
|
1167
|
+
return {
|
|
1168
|
+
jsonrpc: '2.0',
|
|
1169
|
+
id: id,
|
|
1170
|
+
error: { code: -32602, message: error.message },
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1155
1174
|
default:
|
|
1156
1175
|
return {
|
|
1157
1176
|
jsonrpc: '2.0',
|
package/dist/mcp/tools/seo.js
CHANGED
|
@@ -76,7 +76,6 @@ function generateQuickWins(report) {
|
|
|
76
76
|
async function seoAnalyze(args) {
|
|
77
77
|
const url = String(args.url || '');
|
|
78
78
|
const categories = args.categories;
|
|
79
|
-
const verbose = Boolean(args.verbose);
|
|
80
79
|
if (!url) {
|
|
81
80
|
return {
|
|
82
81
|
content: [{ type: 'text', text: 'Error: url is required' }],
|
|
@@ -121,26 +120,21 @@ async function seoAnalyze(args) {
|
|
|
121
120
|
}));
|
|
122
121
|
}
|
|
123
122
|
if (summary.warnings.length > 0) {
|
|
124
|
-
output.warnings = summary.warnings.
|
|
123
|
+
output.warnings = summary.warnings.map(c => ({
|
|
125
124
|
name: c.name,
|
|
126
125
|
message: c.message,
|
|
127
126
|
recommendation: c.recommendation,
|
|
128
127
|
}));
|
|
129
|
-
if (!verbose && summary.warnings.length > 10) {
|
|
130
|
-
output.warningsNote = `Showing 10 of ${summary.warnings.length} warnings. Use verbose=true to see all.`;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
if (verbose) {
|
|
134
|
-
output.detailedAnalysis = {
|
|
135
|
-
title: report.title,
|
|
136
|
-
metaDescription: report.metaDescription,
|
|
137
|
-
headings: report.headings,
|
|
138
|
-
content: report.content,
|
|
139
|
-
links: report.links,
|
|
140
|
-
images: report.images,
|
|
141
|
-
technical: report.technical,
|
|
142
|
-
};
|
|
143
128
|
}
|
|
129
|
+
output.detailedAnalysis = {
|
|
130
|
+
title: report.title,
|
|
131
|
+
metaDescription: report.metaDescription,
|
|
132
|
+
headings: report.headings,
|
|
133
|
+
content: report.content,
|
|
134
|
+
links: report.links,
|
|
135
|
+
images: report.images,
|
|
136
|
+
technical: report.technical,
|
|
137
|
+
};
|
|
144
138
|
return {
|
|
145
139
|
content: [{
|
|
146
140
|
type: 'text',
|
|
@@ -348,11 +342,6 @@ Perfect for analyzing your localhost dev server or any public URL. Categories in
|
|
|
348
342
|
items: { type: 'string' },
|
|
349
343
|
description: 'Filter by specific categories (e.g., ["meta", "security", "performance"]). Leave empty for all.',
|
|
350
344
|
},
|
|
351
|
-
verbose: {
|
|
352
|
-
type: 'boolean',
|
|
353
|
-
description: 'Include detailed analysis (headings, links, images breakdown)',
|
|
354
|
-
default: false,
|
|
355
|
-
},
|
|
356
345
|
},
|
|
357
346
|
required: ['url'],
|
|
358
347
|
},
|
package/dist/version.js
CHANGED