mcp-gov 1.1.0 → 1.2.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.
Files changed (2) hide show
  1. package/bin/mcp-gov.js +58 -62
  2. package/package.json +2 -3
package/bin/mcp-gov.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * mcp-gov - Interactive CLI for MCP Governance System
4
4
  */
5
5
 
6
- import inquirer from 'inquirer';
6
+ import * as readline from 'node:readline';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { existsSync, readFileSync, readdirSync } from 'node:fs';
9
9
  import { join, dirname } from 'node:path';
@@ -14,7 +14,7 @@ const __filename = fileURLToPath(import.meta.url);
14
14
  const __dirname = dirname(__filename);
15
15
 
16
16
  // Get version from package.json
17
- let version = '1.0.0';
17
+ let version = '1.1.0';
18
18
  try {
19
19
  const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
20
20
  version = pkg.version;
@@ -22,59 +22,62 @@ try {
22
22
  // ignore
23
23
  }
24
24
 
25
- console.log(`\nMCP Governance System v${version}\n`);
25
+ const rl = readline.createInterface({
26
+ input: process.stdin,
27
+ output: process.stdout
28
+ });
26
29
 
27
- async function main() {
28
- // Step 1: Select action
29
- const { action } = await inquirer.prompt([
30
- {
31
- type: 'list',
32
- name: 'action',
33
- message: 'Select action:',
34
- choices: [
35
- { name: 'Wrap MCP servers', value: 'wrap' },
36
- { name: 'Unwrap MCP servers', value: 'unwrap' },
37
- { name: 'View audit logs', value: 'logs' },
38
- { name: 'Edit rules', value: 'rules' }
39
- ]
40
- }
41
- ]);
30
+ function ask(question) {
31
+ return new Promise((resolve) => {
32
+ rl.question(question, resolve);
33
+ });
34
+ }
42
35
 
43
- // Handle each action
44
- switch (action) {
45
- case 'wrap':
36
+ async function main() {
37
+ console.log(`\nMCP Governance System v${version}\n`);
38
+ console.log('Select action:');
39
+ console.log(' 1) Wrap MCP servers');
40
+ console.log(' 2) Unwrap MCP servers');
41
+ console.log(' 3) View audit logs');
42
+ console.log(' 4) Edit rules');
43
+ console.log('');
44
+
45
+ const choice = await ask('Enter choice [1-4]: ');
46
+
47
+ switch (choice.trim()) {
48
+ case '1':
46
49
  await handleWrap();
47
50
  break;
48
- case 'unwrap':
51
+ case '2':
49
52
  await handleUnwrap();
50
53
  break;
51
- case 'logs':
54
+ case '3':
52
55
  await handleLogs();
53
56
  break;
54
- case 'rules':
57
+ case '4':
55
58
  await handleRules();
56
59
  break;
60
+ default:
61
+ console.log('Invalid choice');
62
+ rl.close();
63
+ process.exit(1);
57
64
  }
58
65
  }
59
66
 
60
67
  async function handleWrap() {
61
- const { configPath } = await inquirer.prompt([
62
- {
63
- type: 'input',
64
- name: 'configPath',
65
- message: 'Enter config path:',
66
- default: join(homedir(), '.config', 'claude', 'config.json')
67
- }
68
- ]);
68
+ const defaultPath = join(homedir(), '.config', 'claude', 'config.json');
69
+ const configPath = await ask(`Enter config path [${defaultPath}]: `);
70
+ const path = configPath.trim() || defaultPath;
71
+ rl.close();
69
72
 
70
- if (!existsSync(configPath)) {
71
- console.error(`\nError: Config file not found: ${configPath}`);
73
+ if (!existsSync(path)) {
74
+ console.error(`\nError: Config file not found: ${path}`);
72
75
  process.exit(1);
73
76
  }
74
77
 
75
78
  console.log(`\nWrapping servers...\n`);
76
79
 
77
- const child = spawn('node', [join(__dirname, 'mcp-gov-wrap.js'), '--config', configPath], {
80
+ const child = spawn('node', [join(__dirname, 'mcp-gov-wrap.js'), '--config', path], {
78
81
  stdio: 'inherit'
79
82
  });
80
83
 
@@ -84,23 +87,19 @@ async function handleWrap() {
84
87
  }
85
88
 
86
89
  async function handleUnwrap() {
87
- const { configPath } = await inquirer.prompt([
88
- {
89
- type: 'input',
90
- name: 'configPath',
91
- message: 'Enter config path:',
92
- default: join(homedir(), '.config', 'claude', 'config.json')
93
- }
94
- ]);
90
+ const defaultPath = join(homedir(), '.config', 'claude', 'config.json');
91
+ const configPath = await ask(`Enter config path [${defaultPath}]: `);
92
+ const path = configPath.trim() || defaultPath;
93
+ rl.close();
95
94
 
96
- if (!existsSync(configPath)) {
97
- console.error(`\nError: Config file not found: ${configPath}`);
95
+ if (!existsSync(path)) {
96
+ console.error(`\nError: Config file not found: ${path}`);
98
97
  process.exit(1);
99
98
  }
100
99
 
101
100
  console.log(`\nUnwrapping servers...\n`);
102
101
 
103
- const child = spawn('node', [join(__dirname, 'mcp-gov-unwrap.js'), '--config', configPath], {
102
+ const child = spawn('node', [join(__dirname, 'mcp-gov-unwrap.js'), '--config', path], {
104
103
  stdio: 'inherit'
105
104
  });
106
105
 
@@ -111,6 +110,7 @@ async function handleUnwrap() {
111
110
 
112
111
  async function handleLogs() {
113
112
  const logsDir = join(homedir(), '.mcp-gov', 'logs');
113
+ rl.close();
114
114
 
115
115
  if (!existsSync(logsDir)) {
116
116
  console.log('\nNo audit logs found yet.');
@@ -125,27 +125,22 @@ async function handleLogs() {
125
125
  return;
126
126
  }
127
127
 
128
- const { logFile } = await inquirer.prompt([
129
- {
130
- type: 'list',
131
- name: 'logFile',
132
- message: 'Select log file:',
133
- choices: logFiles
134
- }
135
- ]);
128
+ // Show all log files
129
+ for (const logFile of logFiles) {
130
+ const logPath = join(logsDir, logFile);
131
+ const content = readFileSync(logPath, 'utf8');
132
+ const lines = content.trim().split('\n');
133
+ const lastLines = lines.slice(-20);
136
134
 
137
- const logPath = join(logsDir, logFile);
138
- const content = readFileSync(logPath, 'utf8');
139
- const lines = content.trim().split('\n');
140
- const lastLines = lines.slice(-50); // Show last 50 lines
141
-
142
- console.log(`\n--- ${logFile} (last ${lastLines.length} entries) ---\n`);
143
- console.log(lastLines.join('\n'));
144
- console.log(`\n--- End of log ---\n`);
135
+ console.log(`\n--- ${logFile} (last ${lastLines.length} entries) ---\n`);
136
+ console.log(lastLines.join('\n'));
137
+ }
138
+ console.log(`\n--- End of logs ---\n`);
145
139
  }
146
140
 
147
141
  async function handleRules() {
148
142
  const rulesPath = join(homedir(), '.mcp-gov', 'rules.json');
143
+ rl.close();
149
144
 
150
145
  if (!existsSync(rulesPath)) {
151
146
  console.log(`\nRules file not found: ${rulesPath}`);
@@ -170,6 +165,7 @@ async function handleRules() {
170
165
  }
171
166
 
172
167
  main().catch((err) => {
168
+ rl.close();
173
169
  console.error('Error:', err.message);
174
170
  process.exit(1);
175
171
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-gov",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP Governance System - Permission control and audit logging for Model Context Protocol servers",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -46,8 +46,7 @@
46
46
  "dependencies": {
47
47
  "@modelcontextprotocol/sdk": "^0.5.0",
48
48
  "axios": "^1.6.0",
49
- "dotenv": "^16.0.0",
50
- "inquirer": "^13.2.1"
49
+ "dotenv": "^16.0.0"
51
50
  },
52
51
  "devDependencies": {
53
52
  "@types/node": "^25.0.10"