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.
- package/bin/mcp-gov.js +64 -64
- 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
|
|
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.
|
|
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
|
-
|
|
25
|
+
const rl = readline.createInterface({
|
|
26
|
+
input: process.stdin,
|
|
27
|
+
output: process.stdout
|
|
28
|
+
});
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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 '
|
|
51
|
+
case '2':
|
|
49
52
|
await handleUnwrap();
|
|
50
53
|
break;
|
|
51
|
-
case '
|
|
54
|
+
case '3':
|
|
52
55
|
await handleLogs();
|
|
53
56
|
break;
|
|
54
|
-
case '
|
|
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
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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',
|
|
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
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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',
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
|
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"
|