mcp-gov 1.1.0 → 1.2.1

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 +64 -64
  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,64 @@ 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
- ]);
69
-
70
- if (!existsSync(configPath)) {
71
- console.error(`\nError: Config file not found: ${configPath}`);
68
+ const defaultPath = '~/.config/claude/config.json';
69
+ const fullDefault = join(homedir(), '.config', 'claude', 'config.json');
70
+ const configPath = await ask(`Enter config path [${defaultPath}]: `);
71
+ const input = configPath.trim() || fullDefault;
72
+ const path = input.startsWith('~') ? input.replace('~', homedir()) : input;
73
+ rl.close();
74
+
75
+ if (!existsSync(path)) {
76
+ console.error(`\nError: Config file not found: ${path}`);
72
77
  process.exit(1);
73
78
  }
74
79
 
75
80
  console.log(`\nWrapping servers...\n`);
76
81
 
77
- const child = spawn('node', [join(__dirname, 'mcp-gov-wrap.js'), '--config', configPath], {
82
+ const child = spawn('node', [join(__dirname, 'mcp-gov-wrap.js'), '--config', path], {
78
83
  stdio: 'inherit'
79
84
  });
80
85
 
@@ -84,23 +89,21 @@ async function handleWrap() {
84
89
  }
85
90
 
86
91
  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
- ]);
95
-
96
- if (!existsSync(configPath)) {
97
- console.error(`\nError: Config file not found: ${configPath}`);
92
+ const defaultPath = '~/.config/claude/config.json';
93
+ const fullDefault = join(homedir(), '.config', 'claude', 'config.json');
94
+ const configPath = await ask(`Enter config path [${defaultPath}]: `);
95
+ const input = configPath.trim() || fullDefault;
96
+ const path = input.startsWith('~') ? input.replace('~', homedir()) : input;
97
+ rl.close();
98
+
99
+ if (!existsSync(path)) {
100
+ console.error(`\nError: Config file not found: ${path}`);
98
101
  process.exit(1);
99
102
  }
100
103
 
101
104
  console.log(`\nUnwrapping servers...\n`);
102
105
 
103
- const child = spawn('node', [join(__dirname, 'mcp-gov-unwrap.js'), '--config', configPath], {
106
+ const child = spawn('node', [join(__dirname, 'mcp-gov-unwrap.js'), '--config', path], {
104
107
  stdio: 'inherit'
105
108
  });
106
109
 
@@ -111,6 +114,7 @@ async function handleUnwrap() {
111
114
 
112
115
  async function handleLogs() {
113
116
  const logsDir = join(homedir(), '.mcp-gov', 'logs');
117
+ rl.close();
114
118
 
115
119
  if (!existsSync(logsDir)) {
116
120
  console.log('\nNo audit logs found yet.');
@@ -125,27 +129,22 @@ async function handleLogs() {
125
129
  return;
126
130
  }
127
131
 
128
- const { logFile } = await inquirer.prompt([
129
- {
130
- type: 'list',
131
- name: 'logFile',
132
- message: 'Select log file:',
133
- choices: logFiles
134
- }
135
- ]);
136
-
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
132
+ // Show all log files
133
+ for (const logFile of logFiles) {
134
+ const logPath = join(logsDir, logFile);
135
+ const content = readFileSync(logPath, 'utf8');
136
+ const lines = content.trim().split('\n');
137
+ const lastLines = lines.slice(-20);
141
138
 
142
- console.log(`\n--- ${logFile} (last ${lastLines.length} entries) ---\n`);
143
- console.log(lastLines.join('\n'));
144
- console.log(`\n--- End of log ---\n`);
139
+ console.log(`\n--- ${logFile} (last ${lastLines.length} entries) ---\n`);
140
+ console.log(lastLines.join('\n'));
141
+ }
142
+ console.log(`\n--- End of logs ---\n`);
145
143
  }
146
144
 
147
145
  async function handleRules() {
148
146
  const rulesPath = join(homedir(), '.mcp-gov', 'rules.json');
147
+ rl.close();
149
148
 
150
149
  if (!existsSync(rulesPath)) {
151
150
  console.log(`\nRules file not found: ${rulesPath}`);
@@ -170,6 +169,7 @@ async function handleRules() {
170
169
  }
171
170
 
172
171
  main().catch((err) => {
172
+ rl.close();
173
173
  console.error('Error:', err.message);
174
174
  process.exit(1);
175
175
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-gov",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
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"