vcluster-yaml-mcp-server 1.0.1 → 1.0.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 CHANGED
@@ -76,6 +76,11 @@ npx -p vcluster-yaml-mcp-server vcluster-yaml query sync --format table
76
76
  # Or install globally
77
77
  npm install -g vcluster-yaml-mcp-server
78
78
  vcluster-yaml query sync --format table
79
+
80
+ # Validate configurations with ease
81
+ vcluster-yaml validate my-config.yaml
82
+ cat my-config.yaml | vcluster-yaml validate -
83
+ vcluster-yaml validate my-config.yaml --schema-version v0.24.0
79
84
  ```
80
85
 
81
86
  📖 **[Full CLI Documentation →](docs/CLI.md)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vcluster-yaml-mcp-server",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "MCP server for querying vcluster YAML configurations using jq",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -0,0 +1,44 @@
1
+ /**
2
+ * CLI utility functions
3
+ * Provides helpers for stdin reading and file operations
4
+ */
5
+
6
+ import { readFile } from 'fs/promises';
7
+ import { stdin } from 'process';
8
+
9
+ /**
10
+ * Read content from stdin
11
+ * Used for piping content to CLI commands
12
+ * @returns {Promise<string>} The content read from stdin
13
+ */
14
+ export async function readStdin() {
15
+ return new Promise((resolve, reject) => {
16
+ let data = '';
17
+
18
+ stdin.setEncoding('utf8');
19
+ stdin.on('data', chunk => data += chunk);
20
+ stdin.on('end', () => resolve(data));
21
+ stdin.on('error', reject);
22
+ });
23
+ }
24
+
25
+ /**
26
+ * Read content from a file or stdin based on the file argument
27
+ * @param {string|undefined} file - File path, '-' for stdin, or undefined for stdin
28
+ * @returns {Promise<{content: string, source: string}>} The content and its source
29
+ */
30
+ export async function readContentSource(file) {
31
+ // Read from stdin if no file provided or file is '-'
32
+ if (!file || file === '-') {
33
+ const content = await readStdin();
34
+ return { content, source: 'stdin' };
35
+ }
36
+
37
+ // Read from file
38
+ try {
39
+ const content = await readFile(file, 'utf-8');
40
+ return { content, source: file };
41
+ } catch (error) {
42
+ throw new Error(`Cannot read file '${file}': ${error.message}`);
43
+ }
44
+ }
package/src/cli.js CHANGED
@@ -9,6 +9,7 @@
9
9
  import { Command } from 'commander';
10
10
  import { handleQuery, handleListVersions, handleValidate } from './cli-handlers.js';
11
11
  import { formatOutput } from './formatters.js';
12
+ import { readContentSource } from './cli-utils.js';
12
13
 
13
14
  const program = new Command();
14
15
 
@@ -22,8 +23,14 @@ program
22
23
  .command('query <query>')
23
24
  .description('Search for vCluster configuration fields')
24
25
  .option('--file <file>', 'Configuration file to search', 'chart/values.yaml')
25
- .option('--version <version>', 'vCluster version or branch', 'main')
26
+ .option('-s, --schema-version <version>', 'vCluster version or branch', 'main')
26
27
  .option('-f, --format <format>', 'Output format (json, yaml, table)', 'json')
28
+ .addHelpText('after', `
29
+ Examples:
30
+ $ vcluster-yaml query sync
31
+ $ vcluster-yaml query sync --schema-version v0.24.0
32
+ $ vcluster-yaml query "controlPlane.replicas" --format table
33
+ `)
27
34
  .action(async (query, options) => {
28
35
  try {
29
36
  // Validate format option
@@ -32,9 +39,15 @@ program
32
39
  process.exit(1);
33
40
  }
34
41
 
42
+ // Add validation for empty query
43
+ if (!query || query.trim() === '') {
44
+ console.error(`Error: Query cannot be empty. Try 'vcluster-yaml query sync' or see examples with --help`);
45
+ process.exit(1);
46
+ }
47
+
35
48
  const result = await handleQuery(query, {
36
49
  file: options.file,
37
- version: options.version
50
+ version: options.schemaVersion
38
51
  });
39
52
 
40
53
  if (!result.success) {
@@ -91,11 +104,22 @@ program
91
104
 
92
105
  // Validate command
93
106
  program
94
- .command('validate <content>')
107
+ .command('validate [file]')
95
108
  .description('Validate vCluster configuration')
96
- .option('--version <version>', 'vCluster version for schema', 'main')
109
+ .option('-s, --schema-version <version>', 'vCluster version for schema', 'main')
97
110
  .option('-f, --format <format>', 'Output format (json, yaml, table)', 'json')
98
- .action(async (content, options) => {
111
+ .addHelpText('after', `
112
+ Arguments:
113
+ file YAML file to validate (use '-' for stdin, omit to read from stdin)
114
+
115
+ Examples:
116
+ $ vcluster-yaml validate vcluster.yaml
117
+ $ vcluster-yaml validate vcluster.yaml --schema-version v0.24.0
118
+ $ cat vcluster.yaml | vcluster-yaml validate -
119
+ $ vcluster-yaml validate - < vcluster.yaml
120
+ $ vcluster-yaml validate vcluster.yaml --format table
121
+ `)
122
+ .action(async (file, options) => {
99
123
  try {
100
124
  // Validate format option
101
125
  if (!['json', 'yaml', 'table'].includes(options.format)) {
@@ -103,8 +127,24 @@ program
103
127
  process.exit(1);
104
128
  }
105
129
 
130
+ // Read content from file or stdin
131
+ let content;
132
+ try {
133
+ const result = await readContentSource(file);
134
+ content = result.content;
135
+ } catch (error) {
136
+ console.error(`Error: ${error.message}`);
137
+ process.exit(1);
138
+ }
139
+
140
+ // Check for empty content
141
+ if (!content || content.trim() === '') {
142
+ console.error(`Error: No content to validate. Please provide a file path or pipe content via stdin.`);
143
+ process.exit(1);
144
+ }
145
+
106
146
  const result = await handleValidate(content, {
107
- version: options.version
147
+ version: options.schemaVersion
108
148
  });
109
149
 
110
150
  // For validation, always output the result (even if not successful)