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 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-docs": {
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
+ }
@@ -32,6 +32,7 @@ export interface EmbeddingEntry {
32
32
  keywords: string[];
33
33
  section?: string;
34
34
  parentPath?: string;
35
+ content?: string;
35
36
  vector: number[];
36
37
  }
37
38
  export interface SearchOptions {
@@ -22,6 +22,7 @@ export declare class MCPServer {
22
22
  private sseClients;
23
23
  private initialized;
24
24
  private toolRegistry;
25
+ private promptRegistry;
25
26
  private aiClient?;
26
27
  constructor(options?: MCPServerOptions);
27
28
  private indexReady;
@@ -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-docs',
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
- return { jsonrpc: '2.0', id: id, result: { prompts: [] } };
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',
@@ -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.slice(0, verbose ? undefined : 10).map(c => ({
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
@@ -1,4 +1,4 @@
1
- const VERSION = '1.0.40';
1
+ const VERSION = '1.0.41-next.2e33802';
2
2
  let _version = null;
3
3
  export async function getVersion() {
4
4
  if (_version)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recker",
3
- "version": "1.0.40",
3
+ "version": "1.0.41-next.2e33802",
4
4
  "description": "AI & DevX focused HTTP client for Node.js 18+",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",