@redpanda-data/docs-extensions-and-macros 4.13.5 → 4.14.0
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/bin/doc-tools-mcp.js +84 -131
- package/bin/doc-tools.js +105 -192
- package/bin/mcp-tools/generated-docs-review.js +11 -158
- package/bin/mcp-tools/index.js +0 -4
- package/bin/mcp-tools/mcp-validation.js +44 -149
- package/cli-utils/github-token.js +6 -2
- package/mcp/COSTS.adoc +7 -17
- package/mcp/DEVELOPMENT.adoc +2 -175
- package/mcp/README.adoc +27 -61
- package/mcp/WRITER_EXTENSION_GUIDE.adoc +128 -738
- package/package.json +1 -1
- package/tools/redpanda-connect/rpcn-connector-docs-handler.js +60 -60
- package/bin/mcp-tools/content-review.js +0 -196
- package/bin/mcp-tools/frontmatter.js +0 -138
- package/bin/mcp-tools/prompt-discovery.js +0 -283
- package/mcp/prompts/README.adoc +0 -183
- package/mcp/prompts/property-docs-guide.md +0 -283
- package/mcp/prompts/review-for-style.md +0 -128
- package/mcp/prompts/rpcn-connector-docs-guide.md +0 -126
- package/mcp/prompts/write-new-guide.md +0 -222
- package/mcp/team-standards/style-guide.md +0 -321
- package/mcp/templates/README.adoc +0 -212
- package/mcp/templates/prompt-review-template.md +0 -80
- package/mcp/templates/prompt-write-template.md +0 -110
- package/mcp/templates/resource-template.md +0 -76
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt Discovery and Caching
|
|
3
|
-
*
|
|
4
|
-
* Automatically discovers prompts from the mcp/prompts directory.
|
|
5
|
-
* Caches prompt content and metadata for performance.
|
|
6
|
-
* Supports file watching in development mode.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const { parsePromptFile, validateFrontmatter } = require('./frontmatter');
|
|
12
|
-
const { validatePromptName } = require('./mcp-validation');
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* In-memory prompt cache
|
|
16
|
-
*/
|
|
17
|
-
class PromptCache {
|
|
18
|
-
constructor() {
|
|
19
|
-
this.prompts = new Map(); // name -> { metadata, content, filePath }
|
|
20
|
-
this.watchers = [];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Set prompt in cache
|
|
25
|
-
* @param {string} name - Prompt name
|
|
26
|
-
* @param {Object} data - Prompt data
|
|
27
|
-
*/
|
|
28
|
-
set(name, data) {
|
|
29
|
-
this.prompts.set(name, data);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get prompt from cache
|
|
34
|
-
* @param {string} name - Prompt name
|
|
35
|
-
* @returns {Object|null} Prompt data or null
|
|
36
|
-
*/
|
|
37
|
-
get(name) {
|
|
38
|
-
return this.prompts.get(name) || null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get all prompts
|
|
43
|
-
* @returns {Array} Array of prompt objects
|
|
44
|
-
*/
|
|
45
|
-
getAll() {
|
|
46
|
-
return Array.from(this.prompts.values());
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Get all prompt names
|
|
51
|
-
* @returns {Array} Array of prompt names
|
|
52
|
-
*/
|
|
53
|
-
getNames() {
|
|
54
|
-
return Array.from(this.prompts.keys());
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Check if prompt exists
|
|
59
|
-
* @param {string} name - Prompt name
|
|
60
|
-
* @returns {boolean}
|
|
61
|
-
*/
|
|
62
|
-
has(name) {
|
|
63
|
-
return this.prompts.has(name);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Clear all prompts
|
|
68
|
-
*/
|
|
69
|
-
clear() {
|
|
70
|
-
this.prompts.clear();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Stop all file watchers
|
|
75
|
-
*/
|
|
76
|
-
stopWatching() {
|
|
77
|
-
this.watchers.forEach(watcher => watcher.close());
|
|
78
|
-
this.watchers = [];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Add a file watcher
|
|
83
|
-
* @param {FSWatcher} watcher - File system watcher
|
|
84
|
-
*/
|
|
85
|
-
addWatcher(watcher) {
|
|
86
|
-
this.watchers.push(watcher);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Default argument formatters for different types
|
|
92
|
-
*/
|
|
93
|
-
const argumentFormatters = {
|
|
94
|
-
'content-append': (args, schema) => {
|
|
95
|
-
if (!args) return '';
|
|
96
|
-
|
|
97
|
-
let result = '\n\n---\n\n';
|
|
98
|
-
|
|
99
|
-
// If there's a 'content' argument, add it specially
|
|
100
|
-
if (args.content) {
|
|
101
|
-
result += `**Content to review:**\n\n${args.content}`;
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Otherwise, format all arguments
|
|
106
|
-
Object.entries(args).forEach(([key, value]) => {
|
|
107
|
-
const argDef = schema?.find(a => a.name === key);
|
|
108
|
-
const label = argDef?.name || key;
|
|
109
|
-
result += `**${label.charAt(0).toUpperCase() + label.slice(1)}:** ${value}\n`;
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
return result;
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
'structured': (args, schema) => {
|
|
116
|
-
if (!args) return '';
|
|
117
|
-
|
|
118
|
-
let result = '\n\n---\n\n';
|
|
119
|
-
Object.entries(args).forEach(([key, value]) => {
|
|
120
|
-
result += `**${key}:** ${value}\n`;
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
return result;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Discover all prompts in the prompts directory
|
|
129
|
-
* @param {string} promptsDir - Path to prompts directory
|
|
130
|
-
* @returns {Array} Array of discovered prompts
|
|
131
|
-
*/
|
|
132
|
-
function discoverPrompts(promptsDir) {
|
|
133
|
-
if (!fs.existsSync(promptsDir)) {
|
|
134
|
-
throw new Error(`Prompts directory not found: ${promptsDir}`);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const files = fs.readdirSync(promptsDir).filter(f => f.endsWith('.md'));
|
|
138
|
-
const prompts = [];
|
|
139
|
-
|
|
140
|
-
for (const file of files) {
|
|
141
|
-
try {
|
|
142
|
-
const name = path.basename(file, '.md');
|
|
143
|
-
validatePromptName(name); // Ensure safe name
|
|
144
|
-
|
|
145
|
-
const filePath = path.join(promptsDir, file);
|
|
146
|
-
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
147
|
-
|
|
148
|
-
const { metadata, content } = parsePromptFile(fileContent, file);
|
|
149
|
-
|
|
150
|
-
// Build prompt object
|
|
151
|
-
const prompt = {
|
|
152
|
-
name,
|
|
153
|
-
description: metadata.description || `Prompt: ${name}`,
|
|
154
|
-
version: metadata.version || '1.0.0',
|
|
155
|
-
arguments: metadata.arguments || [],
|
|
156
|
-
argumentFormat: metadata.argumentFormat || 'content-append',
|
|
157
|
-
content,
|
|
158
|
-
filePath,
|
|
159
|
-
_rawMetadata: metadata
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
prompts.push(prompt);
|
|
163
|
-
} catch (err) {
|
|
164
|
-
console.error(`Error loading prompt ${file}: ${err.message}`);
|
|
165
|
-
// Continue loading other prompts
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return prompts;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Load all prompts into cache
|
|
174
|
-
* @param {string} baseDir - Base directory (repo root)
|
|
175
|
-
* @param {PromptCache} cache - Prompt cache instance
|
|
176
|
-
* @returns {Array} Loaded prompts
|
|
177
|
-
*/
|
|
178
|
-
function loadAllPrompts(baseDir, cache) {
|
|
179
|
-
const promptsDir = path.join(baseDir, 'mcp', 'prompts');
|
|
180
|
-
const prompts = discoverPrompts(promptsDir);
|
|
181
|
-
|
|
182
|
-
// Clear and reload cache
|
|
183
|
-
cache.clear();
|
|
184
|
-
|
|
185
|
-
prompts.forEach(prompt => {
|
|
186
|
-
cache.set(prompt.name, prompt);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
return prompts;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Watch prompts directory for changes (development mode)
|
|
194
|
-
* @param {string} baseDir - Base directory
|
|
195
|
-
* @param {PromptCache} cache - Prompt cache instance
|
|
196
|
-
* @param {Function} onChange - Callback when prompts change
|
|
197
|
-
*/
|
|
198
|
-
function watchPrompts(baseDir, cache, onChange) {
|
|
199
|
-
const promptsDir = path.join(baseDir, 'mcp', 'prompts');
|
|
200
|
-
|
|
201
|
-
if (!fs.existsSync(promptsDir)) {
|
|
202
|
-
console.error(`Cannot watch prompts directory (not found): ${promptsDir}`);
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const watcher = fs.watch(promptsDir, (eventType, filename) => {
|
|
207
|
-
if (!filename || !filename.endsWith('.md')) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
console.error(`Prompt file changed: ${filename} (${eventType})`);
|
|
212
|
-
console.error('Reloading all prompts...');
|
|
213
|
-
|
|
214
|
-
try {
|
|
215
|
-
const prompts = loadAllPrompts(baseDir, cache);
|
|
216
|
-
console.error(`Reloaded ${prompts.length} prompts`);
|
|
217
|
-
|
|
218
|
-
if (onChange) {
|
|
219
|
-
onChange(prompts);
|
|
220
|
-
}
|
|
221
|
-
} catch (err) {
|
|
222
|
-
console.error(`Error reloading prompts: ${err.message}`);
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
cache.addWatcher(watcher);
|
|
227
|
-
console.error('File watching enabled for prompts (dev mode)');
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Build prompt text with arguments
|
|
232
|
-
* @param {Object} prompt - Prompt object from cache
|
|
233
|
-
* @param {Object} args - Arguments provided by user
|
|
234
|
-
* @returns {string} Complete prompt text
|
|
235
|
-
*/
|
|
236
|
-
function buildPromptWithArguments(prompt, args) {
|
|
237
|
-
let promptText = prompt.content;
|
|
238
|
-
|
|
239
|
-
if (!args || Object.keys(args).length === 0) {
|
|
240
|
-
return promptText;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Use the formatter specified by the prompt
|
|
244
|
-
const formatter = argumentFormatters[prompt.argumentFormat];
|
|
245
|
-
if (!formatter) {
|
|
246
|
-
console.error(
|
|
247
|
-
`Unknown argument format: ${prompt.argumentFormat} for prompt ${prompt.name}`
|
|
248
|
-
);
|
|
249
|
-
return promptText;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const formattedArgs = formatter(args, prompt.arguments);
|
|
253
|
-
promptText += formattedArgs;
|
|
254
|
-
|
|
255
|
-
return promptText;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Convert prompts to MCP protocol format
|
|
260
|
-
* @param {Array} prompts - Discovered prompts
|
|
261
|
-
* @returns {Array} Prompts in MCP format
|
|
262
|
-
*/
|
|
263
|
-
function promptsToMcpFormat(prompts) {
|
|
264
|
-
return prompts.map(prompt => ({
|
|
265
|
-
name: prompt.name,
|
|
266
|
-
description: prompt.description,
|
|
267
|
-
arguments: prompt.arguments.map(arg => ({
|
|
268
|
-
name: arg.name,
|
|
269
|
-
description: arg.description,
|
|
270
|
-
required: arg.required
|
|
271
|
-
}))
|
|
272
|
-
}));
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
module.exports = {
|
|
276
|
-
PromptCache,
|
|
277
|
-
discoverPrompts,
|
|
278
|
-
loadAllPrompts,
|
|
279
|
-
watchPrompts,
|
|
280
|
-
buildPromptWithArguments,
|
|
281
|
-
promptsToMcpFormat,
|
|
282
|
-
argumentFormatters
|
|
283
|
-
};
|
package/mcp/prompts/README.adoc
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
= MCP Server Prompts
|
|
2
|
-
|
|
3
|
-
This directory contains prompt files for the Redpanda Docs MCP Server. Prompts provide contextual guides and instructions to LLMs when working with specific documentation tasks.
|
|
4
|
-
|
|
5
|
-
== What are prompts?
|
|
6
|
-
|
|
7
|
-
MCP Prompts are pre-defined instructions that LLMs can access when needed. They provide:
|
|
8
|
-
|
|
9
|
-
* Detailed context about complex workflows
|
|
10
|
-
* Rules and best practices
|
|
11
|
-
* Step-by-step instructions
|
|
12
|
-
* Quality checks and validation
|
|
13
|
-
|
|
14
|
-
== How prompts work
|
|
15
|
-
|
|
16
|
-
. **Writer makes a request**: "Improve the description for cleanup.policy"
|
|
17
|
-
. **Claude detects the topic**: Recognizes this is about property documentation
|
|
18
|
-
. **Retrieves the prompt**: Automatically loads `property-docs-guide.md`
|
|
19
|
-
. **Follows instructions**: Updates overrides correctly, uses proper workflow
|
|
20
|
-
. **Ensures quality**: Applies all rules and validation checks
|
|
21
|
-
|
|
22
|
-
== Available prompts
|
|
23
|
-
|
|
24
|
-
=== property-docs-guide.md
|
|
25
|
-
|
|
26
|
-
**Purpose**: Comprehensive guide for updating Redpanda property documentation
|
|
27
|
-
|
|
28
|
-
**When used**: Automatically retrieved when working with configuration properties
|
|
29
|
-
|
|
30
|
-
**Key content**:
|
|
31
|
-
|
|
32
|
-
* Override system explanation
|
|
33
|
-
* Mandatory rules (no cloud conditionals, no enterprise includes)
|
|
34
|
-
* Workflow instructions (update property-overrides.json, use generate_property_docs tool)
|
|
35
|
-
* Common scenarios and examples
|
|
36
|
-
* Validation steps
|
|
37
|
-
|
|
38
|
-
=== rpcn-connector-docs-guide.md
|
|
39
|
-
|
|
40
|
-
**Purpose**: Comprehensive guide for updating Redpanda Connect connector reference documentation
|
|
41
|
-
|
|
42
|
-
**When used**: Automatically retrieved when working with connector documentation
|
|
43
|
-
|
|
44
|
-
**Key content**:
|
|
45
|
-
|
|
46
|
-
* Override system with `$ref` syntax explanation
|
|
47
|
-
* DRY (Don't Repeat Yourself) principles
|
|
48
|
-
* Repository structure and folder organization
|
|
49
|
-
* Workflow instructions (update overrides.json, use generate_rpcn_connector_docs tool)
|
|
50
|
-
* Quality checks and validation
|
|
51
|
-
* Examples of `$ref` usage
|
|
52
|
-
|
|
53
|
-
== Adding new prompts
|
|
54
|
-
|
|
55
|
-
The MCP server uses automatic prompt discovery. No code editing required!
|
|
56
|
-
|
|
57
|
-
=== 1. Create the markdown file
|
|
58
|
-
|
|
59
|
-
Create a new file in this directory:
|
|
60
|
-
|
|
61
|
-
[,bash]
|
|
62
|
-
----
|
|
63
|
-
prompts/your-prompt-name.md
|
|
64
|
-
----
|
|
65
|
-
|
|
66
|
-
=== 2. Add YAML frontmatter
|
|
67
|
-
|
|
68
|
-
At the top of your file, add metadata:
|
|
69
|
-
|
|
70
|
-
[,markdown]
|
|
71
|
-
----
|
|
72
|
-
---
|
|
73
|
-
description: "Brief description for LLM to understand when to use this"
|
|
74
|
-
version: "1.0.0"
|
|
75
|
-
arguments:
|
|
76
|
-
content:
|
|
77
|
-
description: "The content to process (if needed)"
|
|
78
|
-
required: true
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
# Your Prompt Title
|
|
82
|
-
|
|
83
|
-
This guide explains how to...
|
|
84
|
-
|
|
85
|
-
## Your workflow:
|
|
86
|
-
1. Do this
|
|
87
|
-
2. Then do that
|
|
88
|
-
3. Use the `tool_name` MCP tool to...
|
|
89
|
-
|
|
90
|
-
## Rules you must follow:
|
|
91
|
-
- Never do X
|
|
92
|
-
- Always do Y
|
|
93
|
-
----
|
|
94
|
-
|
|
95
|
-
Required frontmatter fields:
|
|
96
|
-
- description: What the prompt does
|
|
97
|
-
- version: Semantic version (1.0.0)
|
|
98
|
-
- arguments: (optional) Input parameters
|
|
99
|
-
|
|
100
|
-
=== 3. Validate the prompt
|
|
101
|
-
|
|
102
|
-
Check for errors:
|
|
103
|
-
|
|
104
|
-
[,bash]
|
|
105
|
-
----
|
|
106
|
-
npx doc-tools validate-mcp
|
|
107
|
-
----
|
|
108
|
-
|
|
109
|
-
=== 4. Test it
|
|
110
|
-
|
|
111
|
-
Restart Claude Code and test:
|
|
112
|
-
|
|
113
|
-
[,text]
|
|
114
|
-
----
|
|
115
|
-
You: "List available prompts"
|
|
116
|
-
Claude: *shows your new prompt*
|
|
117
|
-
|
|
118
|
-
You: "Use the your-prompt-name prompt"
|
|
119
|
-
Claude: *loads and follows your instructions*
|
|
120
|
-
----
|
|
121
|
-
|
|
122
|
-
== Writing good prompts
|
|
123
|
-
|
|
124
|
-
**Do:**
|
|
125
|
-
|
|
126
|
-
* **Write for LLMs**: Instructions should be direct ("You should..." not "Tell the user to...")
|
|
127
|
-
* **Be specific**: Clear, actionable steps
|
|
128
|
-
* **Include examples**: Show the correct way to do things
|
|
129
|
-
* **Define rules**: List what must/must not be done
|
|
130
|
-
* **Provide context**: Explain why rules exist
|
|
131
|
-
* **Use workflow sections**: Step-by-step instructions
|
|
132
|
-
|
|
133
|
-
**Don't:**
|
|
134
|
-
|
|
135
|
-
* **Don't write for users**: Prompts are consumed by LLMs
|
|
136
|
-
* **Don't be vague**: "Handle it appropriately" is not helpful
|
|
137
|
-
* **Don't skip validation**: Always include quality checks
|
|
138
|
-
* **Don't forget edge cases**: Cover error scenarios
|
|
139
|
-
* **Don't embed in code**: Keep content in .md files
|
|
140
|
-
|
|
141
|
-
== Prompt structure template
|
|
142
|
-
|
|
143
|
-
[,markdown]
|
|
144
|
-
----
|
|
145
|
-
# Title - What This Prompt Does
|
|
146
|
-
|
|
147
|
-
Brief explanation of the purpose.
|
|
148
|
-
|
|
149
|
-
## Overview
|
|
150
|
-
|
|
151
|
-
Context about the system/workflow.
|
|
152
|
-
|
|
153
|
-
## Critical Rules (MANDATORY)
|
|
154
|
-
|
|
155
|
-
- Never do X
|
|
156
|
-
- Always do Y
|
|
157
|
-
- Must include Z
|
|
158
|
-
|
|
159
|
-
## Your workflow:
|
|
160
|
-
|
|
161
|
-
1. First step
|
|
162
|
-
2. Second step
|
|
163
|
-
3. Use the `tool_name` MCP tool to...
|
|
164
|
-
4. Validate the result
|
|
165
|
-
|
|
166
|
-
## Common scenarios
|
|
167
|
-
|
|
168
|
-
### Scenario 1: Description
|
|
169
|
-
Steps to handle this case.
|
|
170
|
-
|
|
171
|
-
### Scenario 2: Description
|
|
172
|
-
Steps to handle this case.
|
|
173
|
-
|
|
174
|
-
## Quality checks you must perform:
|
|
175
|
-
|
|
176
|
-
- Check for A
|
|
177
|
-
- Verify B
|
|
178
|
-
- Ensure C
|
|
179
|
-
|
|
180
|
-
## Validation
|
|
181
|
-
|
|
182
|
-
How to verify everything worked correctly.
|
|
183
|
-
----
|