mcp-gov 1.0.0 → 1.1.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 +175 -0
  2. package/package.json +4 -2
package/bin/mcp-gov.js ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * mcp-gov - Interactive CLI for MCP Governance System
4
+ */
5
+
6
+ import inquirer from 'inquirer';
7
+ import { spawn } from 'node:child_process';
8
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
9
+ import { join, dirname } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { homedir } from 'node:os';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+
16
+ // Get version from package.json
17
+ let version = '1.0.0';
18
+ try {
19
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
20
+ version = pkg.version;
21
+ } catch (e) {
22
+ // ignore
23
+ }
24
+
25
+ console.log(`\nMCP Governance System v${version}\n`);
26
+
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
+ ]);
42
+
43
+ // Handle each action
44
+ switch (action) {
45
+ case 'wrap':
46
+ await handleWrap();
47
+ break;
48
+ case 'unwrap':
49
+ await handleUnwrap();
50
+ break;
51
+ case 'logs':
52
+ await handleLogs();
53
+ break;
54
+ case 'rules':
55
+ await handleRules();
56
+ break;
57
+ }
58
+ }
59
+
60
+ 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}`);
72
+ process.exit(1);
73
+ }
74
+
75
+ console.log(`\nWrapping servers...\n`);
76
+
77
+ const child = spawn('node', [join(__dirname, 'mcp-gov-wrap.js'), '--config', configPath], {
78
+ stdio: 'inherit'
79
+ });
80
+
81
+ child.on('close', (code) => {
82
+ process.exit(code);
83
+ });
84
+ }
85
+
86
+ 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}`);
98
+ process.exit(1);
99
+ }
100
+
101
+ console.log(`\nUnwrapping servers...\n`);
102
+
103
+ const child = spawn('node', [join(__dirname, 'mcp-gov-unwrap.js'), '--config', configPath], {
104
+ stdio: 'inherit'
105
+ });
106
+
107
+ child.on('close', (code) => {
108
+ process.exit(code);
109
+ });
110
+ }
111
+
112
+ async function handleLogs() {
113
+ const logsDir = join(homedir(), '.mcp-gov', 'logs');
114
+
115
+ if (!existsSync(logsDir)) {
116
+ console.log('\nNo audit logs found yet.');
117
+ console.log(`Logs will appear in: ${logsDir}`);
118
+ return;
119
+ }
120
+
121
+ const logFiles = readdirSync(logsDir).filter(f => f.endsWith('.log'));
122
+
123
+ if (logFiles.length === 0) {
124
+ console.log('\nNo audit logs found yet.');
125
+ return;
126
+ }
127
+
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
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`);
145
+ }
146
+
147
+ async function handleRules() {
148
+ const rulesPath = join(homedir(), '.mcp-gov', 'rules.json');
149
+
150
+ if (!existsSync(rulesPath)) {
151
+ console.log(`\nRules file not found: ${rulesPath}`);
152
+ console.log('Run "Wrap MCP servers" first to generate default rules.');
153
+ return;
154
+ }
155
+
156
+ const editor = process.env.EDITOR || process.env.VISUAL || 'nano';
157
+
158
+ console.log(`\nOpening ${rulesPath} in ${editor}...\n`);
159
+
160
+ const child = spawn(editor, [rulesPath], {
161
+ stdio: 'inherit'
162
+ });
163
+
164
+ child.on('close', (code) => {
165
+ if (code === 0) {
166
+ console.log('\nRules saved.');
167
+ }
168
+ process.exit(code);
169
+ });
170
+ }
171
+
172
+ main().catch((err) => {
173
+ console.error('Error:', err.message);
174
+ process.exit(1);
175
+ });
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "mcp-gov",
3
- "version": "1.0.0",
3
+ "version": "1.1.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",
7
7
  "bin": {
8
+ "mcp-gov": "bin/mcp-gov.js",
8
9
  "mcp-gov-proxy": "bin/mcp-gov-proxy.js",
9
10
  "mcp-gov-wrap": "bin/mcp-gov-wrap.js",
10
11
  "mcp-gov-unwrap": "bin/mcp-gov-unwrap.js"
@@ -45,7 +46,8 @@
45
46
  "dependencies": {
46
47
  "@modelcontextprotocol/sdk": "^0.5.0",
47
48
  "axios": "^1.6.0",
48
- "dotenv": "^16.0.0"
49
+ "dotenv": "^16.0.0",
50
+ "inquirer": "^13.2.1"
49
51
  },
50
52
  "devDependencies": {
51
53
  "@types/node": "^25.0.10"