mcp-gov 1.2.5 → 1.3.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.
- package/CHANGELOG.md +72 -0
- package/README.md +59 -1187
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to mcp-gov will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.3.0] - 2026-01-24
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Cleaned up README - reduced from 1200+ lines to ~130 lines
|
|
9
|
+
- Focus on interactive CLI usage
|
|
10
|
+
- Added npm and npx install options
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- CHANGELOG.md to track version history
|
|
14
|
+
|
|
15
|
+
## [1.2.5] - 2026-01-24
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Removed default config path - users must enter path explicitly
|
|
19
|
+
- Added example hint in prompt: `Enter config path (e.g. ~/.claude.json):`
|
|
20
|
+
- Re-prompt on invalid path instead of exiting
|
|
21
|
+
|
|
22
|
+
## [1.2.4] - 2026-01-24
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Default config path changed to `~/.claude.json`
|
|
26
|
+
- Added retry loop when file not found
|
|
27
|
+
|
|
28
|
+
## [1.2.3] - 2026-01-24
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Exit option (5) to interactive menu
|
|
32
|
+
|
|
33
|
+
## [1.2.2] - 2026-01-24
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- ASCII logo banner for `mcp-gov` command
|
|
37
|
+
- Version display below logo
|
|
38
|
+
- ASCII logo in README
|
|
39
|
+
|
|
40
|
+
## [1.2.1] - 2026-01-24
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
- Config path display now shows `~` instead of full home directory path
|
|
44
|
+
|
|
45
|
+
## [1.2.0] - 2026-01-24
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- Switched from `inquirer` to built-in `readline` for zero dependencies
|
|
49
|
+
- Simple numbered menu (1-5) instead of arrow-key selection
|
|
50
|
+
|
|
51
|
+
## [1.1.0] - 2026-01-24
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
- Interactive `mcp-gov` CLI command with menu:
|
|
55
|
+
- Wrap MCP servers
|
|
56
|
+
- Unwrap MCP servers
|
|
57
|
+
- View audit logs
|
|
58
|
+
- Edit rules
|
|
59
|
+
- `postinstall.js` welcome message after npm install
|
|
60
|
+
- `scripts/publish.sh` for npm publishing with pre/post checks
|
|
61
|
+
|
|
62
|
+
## [1.0.0] - 2026-01-24
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
- Initial release
|
|
66
|
+
- `mcp-gov-proxy` - JSON-RPC proxy with permission checking
|
|
67
|
+
- `mcp-gov-wrap` - Wrap MCP servers with governance
|
|
68
|
+
- `mcp-gov-unwrap` - Restore original server config
|
|
69
|
+
- Auto-generated rules with safe defaults
|
|
70
|
+
- Audit logging to `~/.mcp-gov/logs/`
|
|
71
|
+
- Project path in audit logs
|
|
72
|
+
- Support for flat and multi-project config formats
|
package/README.md
CHANGED
|
@@ -1,263 +1,88 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<pre>
|
|
2
3
|
███╗ ███╗ ██████╗██████╗ ██████╗ ██████╗ ██╗ ██╗
|
|
3
4
|
████╗ ████║██╔════╝██╔══██╗ ██╔════╝ ██╔═══██╗██║ ██║
|
|
4
5
|
██╔████╔██║██║ ██████╔╝ ██║ ███╗██║ ██║██║ ██║
|
|
5
6
|
██║╚██╔╝██║██║ ██╔═══╝ ██║ ██║██║ ██║╚██╗ ██╔╝
|
|
6
7
|
██║ ╚═╝ ██║╚██████╗██║ ╚██████╔╝╚██████╔╝ ╚████╔╝
|
|
7
8
|
╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═════╝ ╚═════╝ ╚═══╝
|
|
8
|
-
|
|
9
|
+
</pre>
|
|
10
|
+
</p>
|
|
9
11
|
|
|
10
12
|
# MCP Governance System
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
Permission control and audit logging for Model Context Protocol (MCP) servers.
|
|
13
15
|
|
|
14
|
-
##
|
|
16
|
+
## Install
|
|
15
17
|
|
|
16
18
|
```bash
|
|
17
|
-
#
|
|
19
|
+
# Using npm
|
|
18
20
|
npm install -g mcp-gov
|
|
19
21
|
|
|
20
|
-
#
|
|
21
|
-
mcp-gov
|
|
22
|
+
# Or run directly with npx
|
|
23
|
+
npx mcp-gov
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
- ✅ **Allow**: read, write operations
|
|
26
|
-
- ❌ **Deny**: delete, admin, execute operations
|
|
26
|
+
## Usage
|
|
27
27
|
|
|
28
|
-
**To unwrap (restore original config):**
|
|
29
28
|
```bash
|
|
30
|
-
mcp-gov
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**To customize rules:**
|
|
34
|
-
Edit `~/.mcp-gov/rules.json` - changes take effect immediately!
|
|
35
|
-
|
|
36
|
-
## Features
|
|
37
|
-
|
|
38
|
-
- **Auto-Discovery**: Automatically discovers MCP server tools and generates governance rules with safe defaults
|
|
39
|
-
- **Smart Delta Updates**: Detects new servers and adds rules while preserving your customizations
|
|
40
|
-
- **Permission Control**: Fine-grained rules for read, write, delete, execute, and admin operations
|
|
41
|
-
- **Operation Detection**: Automatic classification of 160+ keywords across 5 operation types
|
|
42
|
-
- **Safe by Default**: Denies destructive operations (delete/admin/execute) unless explicitly allowed
|
|
43
|
-
- **Audit Logging**: Structured JSON logs to stderr with timestamps, tool names, and status
|
|
44
|
-
- **Zero Configuration**: Works out of the box - no manual rule writing required
|
|
45
|
-
- **MCP-Compliant**: Works seamlessly with any MCP client (Claude Code, Droid, etc.)
|
|
46
|
-
- **Middleware Pattern**: Wraps existing MCP servers without modifying tool logic
|
|
47
|
-
|
|
48
|
-
## Installation
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# From npm (recommended)
|
|
52
|
-
npm install -g mcp-gov
|
|
53
|
-
|
|
54
|
-
# Or from source
|
|
55
|
-
git clone https://github.com/yourusername/mcp-gov.git
|
|
56
|
-
cd mcp-gov
|
|
57
|
-
npm install
|
|
58
|
-
sudo npm link
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**Verify installation:**
|
|
62
|
-
```bash
|
|
63
|
-
mcp-gov-wrap --help
|
|
64
|
-
mcp-gov-unwrap --help
|
|
65
|
-
mcp-gov-proxy --help
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## The 3 Commands
|
|
69
|
-
|
|
70
|
-
### 1. `mcp-gov-wrap` - Wrap MCP Servers
|
|
71
|
-
|
|
72
|
-
Automatically wraps MCP servers with governance proxy and generates rules.
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# Minimal (uses all defaults)
|
|
76
|
-
mcp-gov-wrap --config ~/.config/claude/config.json
|
|
77
|
-
|
|
78
|
-
# With custom rules file
|
|
79
|
-
mcp-gov-wrap --config ~/.config/claude/config.json --rules ~/my-rules.json
|
|
80
|
-
|
|
81
|
-
# Wrap and launch a tool after
|
|
82
|
-
mcp-gov-wrap --config ~/.config/claude/config.json --tool "claude chat"
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**What it does:**
|
|
86
|
-
- ✅ Auto-detects unwrapped MCP servers in your config
|
|
87
|
-
- ✅ Wraps them with `mcp-gov-proxy`
|
|
88
|
-
- ✅ Stores original config in `_original` field (for unwrapping later)
|
|
89
|
-
- ✅ Auto-generates rules at `~/.mcp-gov/rules.json` if missing
|
|
90
|
-
- ✅ Creates timestamped backup before modifying config
|
|
91
|
-
- ✅ Supports both flat and Claude Code config formats
|
|
92
|
-
|
|
93
|
-
**First run output:**
|
|
29
|
+
mcp-gov
|
|
94
30
|
```
|
|
95
|
-
Loaded config in flat format
|
|
96
|
-
Found 4 MCP servers
|
|
97
31
|
|
|
98
|
-
No rules file found - generating with safe defaults...
|
|
99
|
-
Discovering tools from 4 server(s)...
|
|
100
|
-
Discovering github...
|
|
101
|
-
✓ Found 15 tool(s), generated 5 rule(s)
|
|
102
|
-
|
|
103
|
-
✓ Generated rules file: ~/.mcp-gov/rules.json
|
|
104
|
-
|
|
105
|
-
Safe defaults applied:
|
|
106
|
-
✓ Allow: read, write
|
|
107
|
-
✗ Deny: delete, admin, execute
|
|
108
|
-
|
|
109
|
-
Server status:
|
|
110
|
-
Total: 4
|
|
111
|
-
Already wrapped: 0
|
|
112
|
-
Need wrapping: 4
|
|
113
|
-
|
|
114
|
-
Wrapping 4 server(s)...
|
|
115
|
-
✓ Created backup: ~/.config/claude/config.json.backup-20260123-123456
|
|
116
|
-
✓ Updated config file: ~/.config/claude/config.json
|
|
117
|
-
|
|
118
|
-
✓ Wrapping complete!
|
|
119
|
-
|
|
120
|
-
To customize governance rules, edit: ~/.mcp-gov/rules.json
|
|
121
32
|
```
|
|
33
|
+
███╗ ███╗ ██████╗██████╗ ██████╗ ██████╗ ██╗ ██╗
|
|
34
|
+
████╗ ████║██╔════╝██╔══██╗ ██╔════╝ ██╔═══██╗██║ ██║
|
|
35
|
+
██╔████╔██║██║ ██████╔╝ ██║ ███╗██║ ██║██║ ██║
|
|
36
|
+
██║╚██╔╝██║██║ ██╔═══╝ ██║ ██║██║ ██║╚██╗ ██╔╝
|
|
37
|
+
██║ ╚═╝ ██║╚██████╗██║ ╚██████╔╝╚██████╔╝ ╚████╔╝
|
|
38
|
+
╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═════╝ ╚═════╝ ╚═══╝
|
|
39
|
+
v1.2.5
|
|
122
40
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
mcp-gov-unwrap --config ~/.config/claude/config.json
|
|
41
|
+
Select action:
|
|
42
|
+
1) Wrap MCP servers
|
|
43
|
+
2) Unwrap MCP servers
|
|
44
|
+
3) View audit logs
|
|
45
|
+
4) Edit rules
|
|
46
|
+
5) Exit
|
|
130
47
|
|
|
131
|
-
|
|
132
|
-
mcp-gov-unwrap --config ~/.config/claude/config.json --tool "claude chat"
|
|
48
|
+
Enter choice [1-5]:
|
|
133
49
|
```
|
|
134
50
|
|
|
135
|
-
|
|
136
|
-
- ✅ Auto-detects wrapped MCP servers (servers with `_original` field)
|
|
137
|
-
- ✅ Restores original `command` and `args` from `_original`
|
|
138
|
-
- ✅ Removes `_original` field and proxy wrapper
|
|
139
|
-
- ✅ Preserves `env` variables unchanged
|
|
140
|
-
- ✅ Creates timestamped backup before modifying config
|
|
141
|
-
- ✅ Idempotent (safe to run multiple times)
|
|
51
|
+
## How It Works
|
|
142
52
|
|
|
143
|
-
**
|
|
53
|
+
**Before wrapping:**
|
|
144
54
|
```
|
|
145
|
-
|
|
146
|
-
Found 4 MCP servers
|
|
147
|
-
|
|
148
|
-
Server status:
|
|
149
|
-
Total: 4
|
|
150
|
-
Wrapped (can unwrap): 4
|
|
151
|
-
Already unwrapped: 0
|
|
152
|
-
|
|
153
|
-
Servers to unwrap:
|
|
154
|
-
- github
|
|
155
|
-
- filesystem
|
|
156
|
-
- memory
|
|
157
|
-
|
|
158
|
-
Unwrapping 4 server(s)...
|
|
159
|
-
✓ Created backup: ~/.config/claude/config.json.backup-20260123-213121
|
|
160
|
-
✓ Updated config file: ~/.config/claude/config.json
|
|
161
|
-
|
|
162
|
-
✓ Unwrapping complete!
|
|
55
|
+
Claude → MCP Server
|
|
163
56
|
```
|
|
164
57
|
|
|
165
|
-
**
|
|
166
|
-
- Test governance on/off quickly
|
|
167
|
-
- Temporarily disable governance for debugging
|
|
168
|
-
- Restore original config if something goes wrong
|
|
169
|
-
|
|
170
|
-
### 3. `mcp-gov-proxy` - Low-Level Proxy (Advanced)
|
|
171
|
-
|
|
172
|
-
The underlying proxy used by `mcp-gov-wrap`. Normally you don't call this directly.
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
mcp-gov-proxy \
|
|
176
|
-
--service filesystem \
|
|
177
|
-
--target "npx -y @modelcontextprotocol/server-filesystem" \
|
|
178
|
-
--rules ~/.mcp-gov/rules.json
|
|
58
|
+
**After wrapping:**
|
|
179
59
|
```
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- Allows or denies operations
|
|
185
|
-
- Logs all operations to stderr (structured JSON)
|
|
186
|
-
|
|
187
|
-
**Parameters:**
|
|
188
|
-
- `--service` (recommended): Service name for rule matching (e.g., "filesystem", "github")
|
|
189
|
-
- `--target` (required): Command to spawn the target MCP server
|
|
190
|
-
- `--rules` (required): Path to rules.json file
|
|
191
|
-
|
|
192
|
-
**Important:** When wrapping with `mcp-gov-wrap`, the `--service` parameter is automatically added using the server name from your config (e.g., `mcpServers.filesystem` → `--service filesystem`). This ensures governance rules match correctly.
|
|
193
|
-
|
|
194
|
-
This command is automatically invoked by `mcp-gov-wrap` - you typically don't need to use it directly.
|
|
195
|
-
|
|
196
|
-
## Rules Configuration
|
|
197
|
-
|
|
198
|
-
### Location
|
|
199
|
-
|
|
200
|
-
Rules are stored at: **`~/.mcp-gov/rules.json`**
|
|
201
|
-
|
|
202
|
-
This file is **auto-generated** on first run with safe defaults. You can edit it to customize permissions.
|
|
203
|
-
|
|
204
|
-
### Format
|
|
205
|
-
|
|
206
|
-
```json
|
|
207
|
-
{
|
|
208
|
-
"_comment": "Auto-generated governance rules. Edit as needed.",
|
|
209
|
-
"_location": "/home/user/.mcp-gov/rules.json",
|
|
210
|
-
"rules": [
|
|
211
|
-
{
|
|
212
|
-
"service": "github",
|
|
213
|
-
"operations": ["read"],
|
|
214
|
-
"permission": "allow",
|
|
215
|
-
"reason": "Allow read operations (optional)"
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
"service": "github",
|
|
219
|
-
"operations": ["write"],
|
|
220
|
-
"permission": "allow"
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
"service": "github",
|
|
224
|
-
"operations": ["delete"],
|
|
225
|
-
"permission": "deny",
|
|
226
|
-
"reason": "Delete operations denied by default for safety"
|
|
227
|
-
}
|
|
228
|
-
]
|
|
229
|
-
}
|
|
60
|
+
Claude → mcp-gov-proxy → MCP Server
|
|
61
|
+
↓
|
|
62
|
+
checks rules
|
|
63
|
+
logs to audit
|
|
230
64
|
```
|
|
231
65
|
|
|
232
|
-
|
|
66
|
+
## Default Rules
|
|
233
67
|
|
|
234
|
-
|
|
235
|
-
- **`operations`** - Array of operation types: `read`, `write`, `delete`, `execute`, `admin`
|
|
236
|
-
- **`permission`** - `allow` or `deny`
|
|
237
|
-
- **`reason`** (optional) - Human-readable explanation
|
|
68
|
+
Rules are auto-generated at `~/.mcp-gov/rules.json`:
|
|
238
69
|
|
|
239
|
-
|
|
70
|
+
| Operation | Default | Examples |
|
|
71
|
+
|-----------|---------|----------|
|
|
72
|
+
| **read** | ✅ Allow | get, list, search, fetch |
|
|
73
|
+
| **write** | ✅ Allow | create, update, add, save |
|
|
74
|
+
| **delete** | ❌ Deny | delete, remove, drop, purge |
|
|
75
|
+
| **execute** | ❌ Deny | run, exec, invoke, trigger |
|
|
76
|
+
| **admin** | ❌ Deny | admin, configure, grant |
|
|
240
77
|
|
|
241
|
-
|
|
78
|
+
## Files
|
|
242
79
|
|
|
243
|
-
|
|
|
244
|
-
|
|
245
|
-
|
|
|
246
|
-
|
|
|
247
|
-
| **delete** | delete, remove, drop, purge, destroy | ❌ Deny |
|
|
248
|
-
| **execute** | execute, run, eval, invoke, trigger | ❌ Deny |
|
|
249
|
-
| **admin** | admin, sudo, grant, revoke, configure | ❌ Deny |
|
|
80
|
+
| Path | Description |
|
|
81
|
+
|------|-------------|
|
|
82
|
+
| `~/.mcp-gov/rules.json` | Governance rules |
|
|
83
|
+
| `~/.mcp-gov/logs/*.log` | Audit logs by service |
|
|
250
84
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
```bash
|
|
254
|
-
# Edit rules file
|
|
255
|
-
vim ~/.mcp-gov/rules.json
|
|
256
|
-
|
|
257
|
-
# Changes take effect immediately - no restart needed!
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Example: Allow Deletes for Specific Service
|
|
85
|
+
## Rules Format
|
|
261
86
|
|
|
262
87
|
```json
|
|
263
88
|
{
|
|
@@ -265,468 +90,8 @@ vim ~/.mcp-gov/rules.json
|
|
|
265
90
|
{
|
|
266
91
|
"service": "github",
|
|
267
92
|
"operations": ["delete"],
|
|
268
|
-
"permission": "allow",
|
|
269
|
-
"reason": "Trusted service - allow deletes"
|
|
270
|
-
}
|
|
271
|
-
]
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Example: Deny All Writes
|
|
276
|
-
|
|
277
|
-
```json
|
|
278
|
-
{
|
|
279
|
-
"rules": [
|
|
280
|
-
{
|
|
281
|
-
"service": "github",
|
|
282
|
-
"operations": ["write"],
|
|
283
93
|
"permission": "deny",
|
|
284
|
-
"reason": "
|
|
285
|
-
}
|
|
286
|
-
]
|
|
287
|
-
}
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
## Complete Workflow
|
|
291
|
-
|
|
292
|
-
```bash
|
|
293
|
-
# 1. Install
|
|
294
|
-
npm install -g mcp-gov
|
|
295
|
-
|
|
296
|
-
# 2. Wrap servers (auto-generates rules)
|
|
297
|
-
mcp-gov-wrap --config ~/.config/claude/config.json
|
|
298
|
-
|
|
299
|
-
# 3. (Optional) Customize rules
|
|
300
|
-
vim ~/.mcp-gov/rules.json
|
|
301
|
-
|
|
302
|
-
# 4. Use your MCP client normally
|
|
303
|
-
claude chat
|
|
304
|
-
|
|
305
|
-
# 5. (Optional) Unwrap to restore original config
|
|
306
|
-
mcp-gov-unwrap --config ~/.config/claude/config.json
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Adding New Servers (Delta Approach)
|
|
310
|
-
|
|
311
|
-
When you add a new MCP server, just run `mcp-gov-wrap` again - it **automatically detects** new servers and adds rules:
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
# 1. Add a new server (using your client's native command)
|
|
315
|
-
claude mcp add slack --command "npx" --args "-y @modelcontextprotocol/server-slack"
|
|
316
|
-
|
|
317
|
-
# 2. Run wrap again - detects the new server
|
|
318
|
-
mcp-gov-wrap --config ~/.config/claude/config.json
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
**What happens:**
|
|
322
|
-
```
|
|
323
|
-
Discovered 1 new server(s) not in rules:
|
|
324
|
-
- slack
|
|
325
|
-
|
|
326
|
-
Generating safe defaults for new servers...
|
|
327
|
-
✓ Added 3 rule(s) for slack
|
|
328
|
-
|
|
329
|
-
✓ Updated rules file: ~/.mcp-gov/rules.json
|
|
330
|
-
|
|
331
|
-
Your existing github rules are preserved!
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
**Smart delta approach:**
|
|
335
|
-
- ✅ Detects servers not in `rules.json`
|
|
336
|
-
- ✅ Adds rules **only for new servers**
|
|
337
|
-
- ✅ **Preserves your customizations** to existing rules
|
|
338
|
-
- ✅ Never overwrites manual edits
|
|
339
|
-
|
|
340
|
-
## Usage Examples
|
|
341
|
-
|
|
342
|
-
### Viewing Audit Logs
|
|
343
|
-
|
|
344
|
-
Audit logs are written to stderr in JSON format. Capture them for monitoring:
|
|
345
|
-
|
|
346
|
-
```bash
|
|
347
|
-
# Redirect stderr to a log file
|
|
348
|
-
mcp-gov-wrap \
|
|
349
|
-
--config ~/.config/claude/config.json \
|
|
350
|
-
--tool "claude chat" \
|
|
351
|
-
2>> ~/.mcp-gov/audit.log
|
|
352
|
-
|
|
353
|
-
# In another terminal, monitor logs in real-time
|
|
354
|
-
tail -f ~/.mcp-gov/audit.log | jq '.'
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
Example audit log entries:
|
|
358
|
-
|
|
359
|
-
```json
|
|
360
|
-
{"timestamp":"2026-01-23T14:30:45.123Z","tool":"github_list_repos","service":"github","operation":"read","status":"allowed"}
|
|
361
|
-
{"timestamp":"2026-01-23T14:31:12.456Z","tool":"github_delete_repo","service":"github","operation":"delete","status":"denied","reason":"Destructive operations require manual approval"}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### Updating Rules
|
|
365
|
-
|
|
366
|
-
To change governance rules:
|
|
367
|
-
|
|
368
|
-
1. Edit `~/.mcp-gov/rules.json`
|
|
369
|
-
2. No need to restart or re-wrap - changes take effect immediately
|
|
370
|
-
3. Next tool call will use the updated rules
|
|
371
|
-
|
|
372
|
-
```bash
|
|
373
|
-
# Edit rules
|
|
374
|
-
vim ~/.mcp-gov/rules.json
|
|
375
|
-
|
|
376
|
-
# No restart needed - just continue using your client
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### Checking Server Status
|
|
380
|
-
|
|
381
|
-
View which servers are wrapped:
|
|
382
|
-
|
|
383
|
-
```bash
|
|
384
|
-
# Show wrapped config
|
|
385
|
-
cat ~/.config/claude/config.json | jq '.mcpServers'
|
|
386
|
-
|
|
387
|
-
# Or for Claude Code format
|
|
388
|
-
cat ~/.config/claude/config.json | jq '.projects.default.mcpServers'
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
Wrapped servers will have `"command": "mcp-gov-proxy"` instead of their original command.
|
|
392
|
-
|
|
393
|
-
### Restoring Original Config
|
|
394
|
-
|
|
395
|
-
**Easiest way - use unwrap:**
|
|
396
|
-
|
|
397
|
-
```bash
|
|
398
|
-
mcp-gov-unwrap --config ~/.config/claude/config.json
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Or restore from backup manually:**
|
|
402
|
-
|
|
403
|
-
```bash
|
|
404
|
-
# List available backups
|
|
405
|
-
ls -lt ~/.config/claude/*.backup-* | head -5
|
|
406
|
-
|
|
407
|
-
# Restore from a backup
|
|
408
|
-
cp ~/.config/claude/config.json.backup-20260123-143022 ~/.config/claude/config.json
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### Direct Proxy Usage (Advanced)
|
|
412
|
-
|
|
413
|
-
For testing or custom integrations, use the proxy directly:
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
# Run a single server through the proxy
|
|
417
|
-
mcp-gov-proxy \
|
|
418
|
-
--target "npx -y @modelcontextprotocol/server-github" \
|
|
419
|
-
--rules ~/.mcp-gov/rules.json
|
|
420
|
-
|
|
421
|
-
# Pipe input/output for testing
|
|
422
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
|
|
423
|
-
mcp-gov-proxy \
|
|
424
|
-
--target "npx -y @modelcontextprotocol/server-github" \
|
|
425
|
-
--rules ~/.mcp-gov/rules.json
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
## Quick Start
|
|
429
|
-
|
|
430
|
-
### 1. Create a governed server
|
|
431
|
-
|
|
432
|
-
```javascript
|
|
433
|
-
import { GovernedMCPServer } from './src/index.js';
|
|
434
|
-
|
|
435
|
-
// Define permission rules
|
|
436
|
-
const rules = {
|
|
437
|
-
github: {
|
|
438
|
-
read: 'allow',
|
|
439
|
-
write: 'allow',
|
|
440
|
-
delete: 'deny', // Block destructive operations
|
|
441
|
-
admin: 'deny'
|
|
442
|
-
}
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
// Create server
|
|
446
|
-
const server = new GovernedMCPServer(
|
|
447
|
-
{ name: 'my-server', version: '1.0.0' },
|
|
448
|
-
rules
|
|
449
|
-
);
|
|
450
|
-
|
|
451
|
-
// Register tools
|
|
452
|
-
server.registerTool(
|
|
453
|
-
{
|
|
454
|
-
name: 'github_list_repos',
|
|
455
|
-
description: 'List repositories',
|
|
456
|
-
inputSchema: { type: 'object', properties: {} }
|
|
457
|
-
},
|
|
458
|
-
async (args) => {
|
|
459
|
-
// Your tool logic here
|
|
460
|
-
return {
|
|
461
|
-
content: [{ type: 'text', text: 'Repositories listed' }]
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
);
|
|
465
|
-
|
|
466
|
-
// Start server
|
|
467
|
-
await server.start();
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
### 2. Run the GitHub example
|
|
471
|
-
|
|
472
|
-
```bash
|
|
473
|
-
# Set up environment
|
|
474
|
-
cd examples/github
|
|
475
|
-
cp .env.example .env
|
|
476
|
-
# Edit .env and add your GitHub token
|
|
477
|
-
|
|
478
|
-
# Run the server
|
|
479
|
-
node server.js
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
### 3. Configure Claude Desktop
|
|
483
|
-
|
|
484
|
-
Add to `~/.config/Claude/claude_desktop_config.json`:
|
|
485
|
-
|
|
486
|
-
```json
|
|
487
|
-
{
|
|
488
|
-
"mcpServers": {
|
|
489
|
-
"github-governed": {
|
|
490
|
-
"command": "node",
|
|
491
|
-
"args": ["/path/to/mcp-gov/examples/github/server.js"],
|
|
492
|
-
"env": {
|
|
493
|
-
"GITHUB_TOKEN": "your_token_here"
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
## Troubleshooting
|
|
501
|
-
|
|
502
|
-
### Rules Auto-Generation
|
|
503
|
-
|
|
504
|
-
**Behavior:** When `--rules` is not provided or the file doesn't exist, rules are **automatically generated**.
|
|
505
|
-
|
|
506
|
-
The wrapper will:
|
|
507
|
-
1. Discover tools from each MCP server
|
|
508
|
-
2. Classify operations (read/write/delete/admin/execute)
|
|
509
|
-
3. Generate rules with safe defaults
|
|
510
|
-
4. Save to `~/.mcp-gov/rules.json` (or specified path)
|
|
511
|
-
|
|
512
|
-
**To disable auto-generation:** Always provide a rules file explicitly with `--rules`.
|
|
513
|
-
|
|
514
|
-
**To regenerate rules:** Delete `~/.mcp-gov/rules.json` and run the wrapper again.
|
|
515
|
-
|
|
516
|
-
### Config file errors
|
|
517
|
-
|
|
518
|
-
**Error:** `Error: Config file not found` or `Error: Invalid config format`
|
|
519
|
-
|
|
520
|
-
**Solution:** Check your config file path and format:
|
|
521
|
-
|
|
522
|
-
```bash
|
|
523
|
-
# Verify file exists
|
|
524
|
-
ls -la ~/.config/claude/config.json
|
|
525
|
-
|
|
526
|
-
# Check JSON is valid
|
|
527
|
-
jq '.' ~/.config/claude/config.json
|
|
528
|
-
|
|
529
|
-
# Check for mcpServers key
|
|
530
|
-
jq 'keys' ~/.config/claude/config.json
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
For Claude Code, the config uses `projects.default.mcpServers` or `projects.<project-name>.mcpServers`.
|
|
534
|
-
For other clients, look for top-level `mcpServers`.
|
|
535
|
-
|
|
536
|
-
### Wrapper says "No servers found"
|
|
537
|
-
|
|
538
|
-
**Error:** `Found 0 MCP servers`
|
|
539
|
-
|
|
540
|
-
**Solution:** Check your config format:
|
|
541
|
-
|
|
542
|
-
```bash
|
|
543
|
-
# Claude Code format
|
|
544
|
-
cat ~/.config/claude/config.json | jq '.projects'
|
|
545
|
-
|
|
546
|
-
# Flat format
|
|
547
|
-
cat ~/.config/claude/config.json | jq '.mcpServers'
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
Make sure you've added at least one server using your client's native command first.
|
|
551
|
-
|
|
552
|
-
### Proxy not blocking operations
|
|
553
|
-
|
|
554
|
-
**Problem:** Operations that should be denied are being allowed.
|
|
555
|
-
|
|
556
|
-
**Solutions:**
|
|
557
|
-
|
|
558
|
-
1. **Verify rules file syntax:**
|
|
559
|
-
```bash
|
|
560
|
-
jq '.' ~/.mcp-gov/rules.json
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
2. **Check service name matches:**
|
|
564
|
-
Tool names like `github_delete_repo` are parsed as service `github`, operation `delete`.
|
|
565
|
-
Your rules should use `"service": "github"`.
|
|
566
|
-
|
|
567
|
-
3. **Check operation detection:**
|
|
568
|
-
```bash
|
|
569
|
-
node -e "import('./src/operation-detector.js').then(m => console.log(m.detectOperation('github_delete_repo')))"
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
4. **Review audit logs:**
|
|
573
|
-
Check stderr output to see what's being detected:
|
|
574
|
-
```bash
|
|
575
|
-
# Logs show what service/operation was detected
|
|
576
|
-
tail ~/.mcp-gov/audit.log | jq '.'
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
### Path issues (Windows)
|
|
580
|
-
|
|
581
|
-
**Problem:** Paths with backslashes or spaces cause errors.
|
|
582
|
-
|
|
583
|
-
**Solution:** Use forward slashes (works on Windows too) or quote paths:
|
|
584
|
-
|
|
585
|
-
```powershell
|
|
586
|
-
# Forward slashes work on Windows
|
|
587
|
-
mcp-gov-wrap --config ~/.config/claude/config.json --rules ~/.mcp-gov/rules.json --tool "claude chat"
|
|
588
|
-
|
|
589
|
-
# Or use quotes for paths with spaces
|
|
590
|
-
mcp-gov-wrap --config "C:\Program Files\Claude\config.json" --rules "C:\mcp-gov\rules.json" --tool "claude chat"
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
### Commands fail after wrapping
|
|
594
|
-
|
|
595
|
-
**Problem:** MCP client fails to start or servers don't respond after wrapping.
|
|
596
|
-
|
|
597
|
-
**Solutions:**
|
|
598
|
-
|
|
599
|
-
1. **Test original command:**
|
|
600
|
-
```bash
|
|
601
|
-
# Test the server command directly
|
|
602
|
-
npx -y @modelcontextprotocol/server-github
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
2. **Test proxy directly:**
|
|
606
|
-
```bash
|
|
607
|
-
# If original works, test through proxy
|
|
608
|
-
mcp-gov-proxy --target "npx -y @modelcontextprotocol/server-github" --rules ~/.mcp-gov/rules.json
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
3. **Restore from backup:**
|
|
612
|
-
```bash
|
|
613
|
-
# If wrapping broke config, restore backup
|
|
614
|
-
ls -lt ~/.config/claude/*.backup.* | head -1
|
|
615
|
-
cp <backup-file> ~/.config/claude/config.json
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
4. **Check for double-wrapping:**
|
|
619
|
-
```bash
|
|
620
|
-
# Verify servers aren't double-wrapped
|
|
621
|
-
cat ~/.config/claude/config.json | jq '.mcpServers'
|
|
622
|
-
|
|
623
|
-
# Should see "mcp-gov-proxy" as command, NOT nested proxies
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### Binary not found after installation
|
|
627
|
-
|
|
628
|
-
**Error:** `command not found: mcp-gov-proxy`
|
|
629
|
-
|
|
630
|
-
**Solution:** Add npm global bin to PATH:
|
|
631
|
-
|
|
632
|
-
**Linux/macOS:**
|
|
633
|
-
```bash
|
|
634
|
-
# Find global bin directory
|
|
635
|
-
npm prefix -g
|
|
636
|
-
|
|
637
|
-
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
|
|
638
|
-
export PATH="$(npm prefix -g)/bin:$PATH"
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
**Windows:**
|
|
642
|
-
```powershell
|
|
643
|
-
# Find global bin directory
|
|
644
|
-
npm prefix -g
|
|
645
|
-
|
|
646
|
-
# Add to PATH in System Environment Variables
|
|
647
|
-
# Or use full path:
|
|
648
|
-
$env:PATH += ";$(npm prefix -g)\bin"
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
### Permission denied on Linux/macOS
|
|
652
|
-
|
|
653
|
-
**Error:** `Permission denied` when running binaries.
|
|
654
|
-
|
|
655
|
-
**Solution:** Make binaries executable:
|
|
656
|
-
|
|
657
|
-
```bash
|
|
658
|
-
chmod +x $(npm prefix -g)/lib/node_modules/mcp-gov/bin/mcp-gov-proxy.js
|
|
659
|
-
chmod +x $(npm prefix -g)/lib/node_modules/mcp-gov/bin/mcp-gov-wrap.js
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
### Audit logs not appearing
|
|
663
|
-
|
|
664
|
-
**Problem:** No logs in stderr or log file.
|
|
665
|
-
|
|
666
|
-
**Solutions:**
|
|
667
|
-
|
|
668
|
-
1. **Ensure stderr is redirected:**
|
|
669
|
-
```bash
|
|
670
|
-
mcp-gov-wrap ... 2>> ~/.mcp-gov/audit.log
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
2. **Check tools are being called:**
|
|
674
|
-
Use your MCP client to call a tool and verify it triggers the proxy.
|
|
675
|
-
|
|
676
|
-
3. **Test proxy directly:**
|
|
677
|
-
```bash
|
|
678
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
|
|
679
|
-
mcp-gov-proxy --target "npx -y @modelcontextprotocol/server-github" --rules ~/.mcp-gov/rules.json \
|
|
680
|
-
2>&1 | tee test.log
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
### Performance issues
|
|
684
|
-
|
|
685
|
-
**Problem:** Tool calls seem slow after adding governance.
|
|
686
|
-
|
|
687
|
-
**Expected:** Proxy overhead should be < 50ms per call.
|
|
688
|
-
|
|
689
|
-
**Solutions:**
|
|
690
|
-
|
|
691
|
-
1. **Check rules file size:**
|
|
692
|
-
Very large rules files (1000+ rules) may slow parsing.
|
|
693
|
-
|
|
694
|
-
2. **Test without proxy:**
|
|
695
|
-
Compare performance with and without governance to isolate the issue.
|
|
696
|
-
|
|
697
|
-
3. **Check network latency:**
|
|
698
|
-
If calling external APIs, most delay is network, not governance.
|
|
699
|
-
|
|
700
|
-
For more help, see [TESTING.md](TESTING.md) or open an issue on GitHub.
|
|
701
|
-
|
|
702
|
-
## Operation Detection
|
|
703
|
-
|
|
704
|
-
The system automatically classifies tools based on keywords in their names:
|
|
705
|
-
|
|
706
|
-
| Operation | Keywords | Default Policy |
|
|
707
|
-
|-----------|----------|----------------|
|
|
708
|
-
| **admin** | admin, superuser, configure, migrate, deploy | Conservative |
|
|
709
|
-
| **delete** | delete, remove, destroy, purge, erase | Conservative |
|
|
710
|
-
| **execute** | execute, run, invoke, trigger, send | Conservative |
|
|
711
|
-
| **write** | create, add, update, modify, edit, write | Moderate |
|
|
712
|
-
| **read** | get, list, fetch, query, search, view | Permissive |
|
|
713
|
-
|
|
714
|
-
Priority order: admin → delete → execute → write → read
|
|
715
|
-
|
|
716
|
-
## Permission Rules
|
|
717
|
-
|
|
718
|
-
### Rules File Format (CLI Tools)
|
|
719
|
-
|
|
720
|
-
For the auto-wrap CLI tools, rules are defined in `rules.json`:
|
|
721
|
-
|
|
722
|
-
```json
|
|
723
|
-
{
|
|
724
|
-
"rules": [
|
|
725
|
-
{
|
|
726
|
-
"service": "github",
|
|
727
|
-
"operations": ["delete", "admin"],
|
|
728
|
-
"permission": "deny",
|
|
729
|
-
"reason": "Destructive operations require manual approval"
|
|
94
|
+
"reason": "Block destructive operations"
|
|
730
95
|
},
|
|
731
96
|
{
|
|
732
97
|
"service": "github",
|
|
@@ -737,520 +102,27 @@ For the auto-wrap CLI tools, rules are defined in `rules.json`:
|
|
|
737
102
|
}
|
|
738
103
|
```
|
|
739
104
|
|
|
740
|
-
|
|
741
|
-
- `service`: Service name (extracted from tool name prefix, e.g., `github_list_repos` → `github`)
|
|
742
|
-
- `operations`: Array of operation types: `["read", "write", "delete", "execute", "admin"]`
|
|
743
|
-
- `permission`: Either `"allow"` or `"deny"`
|
|
744
|
-
- `reason` (optional): Human-readable explanation for deny rules
|
|
745
|
-
|
|
746
|
-
### Multiple Service Examples
|
|
747
|
-
|
|
748
|
-
```json
|
|
749
|
-
{
|
|
750
|
-
"rules": [
|
|
751
|
-
{
|
|
752
|
-
"service": "github",
|
|
753
|
-
"operations": ["delete", "admin"],
|
|
754
|
-
"permission": "deny",
|
|
755
|
-
"reason": "Destructive operations require manual approval"
|
|
756
|
-
},
|
|
757
|
-
{
|
|
758
|
-
"service": "google",
|
|
759
|
-
"operations": ["delete"],
|
|
760
|
-
"permission": "deny",
|
|
761
|
-
"reason": "Prevent accidental deletion of Google Drive files"
|
|
762
|
-
},
|
|
763
|
-
{
|
|
764
|
-
"service": "aws",
|
|
765
|
-
"operations": ["admin", "execute"],
|
|
766
|
-
"permission": "deny",
|
|
767
|
-
"reason": "AWS administrative actions require explicit approval"
|
|
768
|
-
},
|
|
769
|
-
{
|
|
770
|
-
"service": "database",
|
|
771
|
-
"operations": ["delete", "admin"],
|
|
772
|
-
"permission": "deny",
|
|
773
|
-
"reason": "Database modifications must be reviewed"
|
|
774
|
-
},
|
|
775
|
-
{
|
|
776
|
-
"service": "slack",
|
|
777
|
-
"operations": ["delete"],
|
|
778
|
-
"permission": "deny",
|
|
779
|
-
"reason": "Cannot delete messages once sent"
|
|
780
|
-
}
|
|
781
|
-
]
|
|
782
|
-
}
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
### Default Behavior
|
|
786
|
-
|
|
787
|
-
- **Default policy:** `allow` (if no rule matches, operation is allowed)
|
|
788
|
-
- Operations not listed in rules default to allowed
|
|
789
|
-
- Service names are automatically extracted from tool names
|
|
790
|
-
- Rules are evaluated at runtime (no restart needed after changes)
|
|
791
|
-
|
|
792
|
-
### Programmatic API Format
|
|
793
|
-
|
|
794
|
-
For the `GovernedMCPServer` class, rules use a different format:
|
|
795
|
-
|
|
796
|
-
```javascript
|
|
797
|
-
const rules = {
|
|
798
|
-
serviceName: {
|
|
799
|
-
read: 'allow',
|
|
800
|
-
write: 'allow',
|
|
801
|
-
delete: 'deny',
|
|
802
|
-
execute: 'allow',
|
|
803
|
-
admin: 'deny'
|
|
804
|
-
}
|
|
805
|
-
};
|
|
806
|
-
```
|
|
807
|
-
|
|
808
|
-
## Audit Logs
|
|
809
|
-
|
|
810
|
-
### Log Format
|
|
811
|
-
|
|
812
|
-
All tool operations are logged to stderr in JSON format by the proxy:
|
|
813
|
-
|
|
814
|
-
```json
|
|
815
|
-
{
|
|
816
|
-
"timestamp": "2026-01-23T14:30:45.123Z",
|
|
817
|
-
"tool": "github_delete_repo",
|
|
818
|
-
"service": "github",
|
|
819
|
-
"operation": "delete",
|
|
820
|
-
"status": "denied",
|
|
821
|
-
"reason": "Destructive operations require manual approval"
|
|
822
|
-
}
|
|
823
|
-
```
|
|
824
|
-
|
|
825
|
-
**Fields:**
|
|
826
|
-
- `timestamp`: ISO 8601 timestamp (UTC)
|
|
827
|
-
- `tool`: Full tool name as called by the MCP client
|
|
828
|
-
- `service`: Extracted service name (e.g., `github` from `github_delete_repo`)
|
|
829
|
-
- `operation`: Operation type (`read`, `write`, `delete`, `execute`, `admin`)
|
|
830
|
-
- `status`: Either `allowed` or `denied`
|
|
831
|
-
- `reason`: Optional explanation (only for denied operations)
|
|
105
|
+
## Audit Log Format
|
|
832
106
|
|
|
833
|
-
### Capturing Logs
|
|
834
|
-
|
|
835
|
-
Redirect stderr to capture audit logs:
|
|
836
|
-
|
|
837
|
-
```bash
|
|
838
|
-
# Append to log file
|
|
839
|
-
mcp-gov-wrap \
|
|
840
|
-
--config ~/.config/claude/config.json \
|
|
841
|
-
--tool "claude chat" \
|
|
842
|
-
2>> ~/.mcp-gov/audit.log
|
|
843
107
|
```
|
|
844
|
-
|
|
845
|
-
Or with your alias (recommended):
|
|
846
|
-
|
|
847
|
-
```bash
|
|
848
|
-
# Capture stderr to log
|
|
849
|
-
claude-gov 2>> ~/.mcp-gov/audit.log
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
### Real-Time Monitoring
|
|
853
|
-
|
|
854
|
-
Monitor logs in real-time using `tail` and `jq`:
|
|
855
|
-
|
|
856
|
-
```bash
|
|
857
|
-
# Watch logs with pretty formatting
|
|
858
|
-
tail -f ~/.mcp-gov/audit.log | jq '.'
|
|
859
|
-
|
|
860
|
-
# Watch only denied operations
|
|
861
|
-
tail -f ~/.mcp-gov/audit.log | jq -r 'select(.status=="denied")'
|
|
862
|
-
|
|
863
|
-
# Count operations by service
|
|
864
|
-
tail -f ~/.mcp-gov/audit.log | jq -r '.service' | sort | uniq -c
|
|
865
|
-
|
|
866
|
-
# Show timestamp and tool name
|
|
867
|
-
tail -f ~/.mcp-gov/audit.log | jq -r '"\(.timestamp) \(.tool) \(.status)"'
|
|
108
|
+
[AUDIT] 2026-01-24T10:30:45.123Z | DENIED | tool=delete_repo | service=github | operation=delete | project=/home/user/myproject
|
|
868
109
|
```
|
|
869
110
|
|
|
870
|
-
|
|
111
|
+
## CLI Commands
|
|
871
112
|
|
|
872
|
-
|
|
113
|
+
The interactive menu is recommended, but you can also use commands directly:
|
|
873
114
|
|
|
874
115
|
```bash
|
|
875
|
-
#
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
# Count denied operations
|
|
879
|
-
grep '"status":"denied"' ~/.mcp-gov/audit.log | wc -l
|
|
116
|
+
# Wrap servers
|
|
117
|
+
mcp-gov-wrap --config ~/.claude.json
|
|
880
118
|
|
|
881
|
-
#
|
|
882
|
-
|
|
119
|
+
# Unwrap servers
|
|
120
|
+
mcp-gov-unwrap --config ~/.claude.json
|
|
883
121
|
|
|
884
|
-
#
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
# Denied operations with reasons
|
|
888
|
-
jq -r 'select(.status=="denied") | "\(.tool): \(.reason)"' ~/.mcp-gov/audit.log
|
|
889
|
-
|
|
890
|
-
# Operations in the last hour
|
|
891
|
-
jq -r --arg hour "$(date -u +%Y-%m-%dT%H)" 'select(.timestamp | startswith($hour))' ~/.mcp-gov/audit.log
|
|
892
|
-
|
|
893
|
-
# Group by hour
|
|
894
|
-
jq -r '.timestamp[0:13]' ~/.mcp-gov/audit.log | uniq -c
|
|
895
|
-
```
|
|
896
|
-
|
|
897
|
-
### Monitoring Best Practices
|
|
898
|
-
|
|
899
|
-
1. **Rotate logs** to prevent unlimited growth:
|
|
900
|
-
```bash
|
|
901
|
-
# Add to cron (daily rotation)
|
|
902
|
-
0 0 * * * mv ~/.mcp-gov/audit.log ~/.mcp-gov/audit.$(date +\%Y\%m\%d).log && touch ~/.mcp-gov/audit.log
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
2. **Alert on anomalies** using a simple script:
|
|
906
|
-
```bash
|
|
907
|
-
#!/bin/bash
|
|
908
|
-
# alert-on-denied.sh
|
|
909
|
-
tail -f ~/.mcp-gov/audit.log | while read line; do
|
|
910
|
-
status=$(echo $line | jq -r '.status')
|
|
911
|
-
if [ "$status" = "denied" ]; then
|
|
912
|
-
tool=$(echo $line | jq -r '.tool')
|
|
913
|
-
reason=$(echo $line | jq -r '.reason')
|
|
914
|
-
echo "ALERT: Denied operation: $tool ($reason)"
|
|
915
|
-
# Send notification, email, etc.
|
|
916
|
-
fi
|
|
917
|
-
done
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
3. **Export to external systems**:
|
|
921
|
-
```bash
|
|
922
|
-
# Forward to syslog
|
|
923
|
-
tail -f ~/.mcp-gov/audit.log | logger -t mcp-gov
|
|
924
|
-
|
|
925
|
-
# Forward to monitoring service
|
|
926
|
-
tail -f ~/.mcp-gov/audit.log | curl -X POST -H "Content-Type: application/json" \
|
|
927
|
-
-d @- https://your-monitoring-service.com/logs
|
|
928
|
-
```
|
|
929
|
-
|
|
930
|
-
4. **Backup audit logs** regularly:
|
|
931
|
-
```bash
|
|
932
|
-
# Daily backup
|
|
933
|
-
tar -czf ~/backups/mcp-audit-$(date +%Y%m%d).tar.gz ~/.mcp-gov/*.log
|
|
934
|
-
```
|
|
935
|
-
|
|
936
|
-
### Log Retention
|
|
937
|
-
|
|
938
|
-
Consider your retention requirements:
|
|
939
|
-
|
|
940
|
-
- **Development**: 7-30 days
|
|
941
|
-
- **Production**: 90-365 days (or per compliance requirements)
|
|
942
|
-
- **Compliance**: May require indefinite retention and immutability
|
|
943
|
-
|
|
944
|
-
### Privacy Considerations
|
|
945
|
-
|
|
946
|
-
Audit logs may contain sensitive information:
|
|
947
|
-
|
|
948
|
-
- Tool names might reveal user intent
|
|
949
|
-
- Service names show what systems are being accessed
|
|
950
|
-
- Timestamps reveal usage patterns
|
|
951
|
-
|
|
952
|
-
Ensure logs are:
|
|
953
|
-
- Stored securely (appropriate file permissions)
|
|
954
|
-
- Encrypted at rest if required
|
|
955
|
-
- Access-controlled
|
|
956
|
-
- Included in backup strategies
|
|
957
|
-
|
|
958
|
-
### Example: Continuous Monitoring Dashboard
|
|
959
|
-
|
|
960
|
-
```bash
|
|
961
|
-
#!/bin/bash
|
|
962
|
-
# mcp-dashboard.sh - Simple audit log dashboard
|
|
963
|
-
|
|
964
|
-
watch -n 5 '
|
|
965
|
-
echo "=== MCP Governance Dashboard ==="
|
|
966
|
-
echo ""
|
|
967
|
-
echo "Total Operations: $(wc -l < ~/.mcp-gov/audit.log)"
|
|
968
|
-
echo "Allowed: $(grep -c "\"status\":\"allowed\"" ~/.mcp-gov/audit.log || echo 0)"
|
|
969
|
-
echo "Denied: $(grep -c "\"status\":\"denied\"" ~/.mcp-gov/audit.log || echo 0)"
|
|
970
|
-
echo ""
|
|
971
|
-
echo "=== Top Services ==="
|
|
972
|
-
jq -r ".service" ~/.mcp-gov/audit.log | sort | uniq -c | sort -rn | head -5
|
|
973
|
-
echo ""
|
|
974
|
-
echo "=== Recent Denied Operations ==="
|
|
975
|
-
jq -r "select(.status==\"denied\") | \"\(.timestamp) \(.tool)\"" ~/.mcp-gov/audit.log | tail -5
|
|
976
|
-
'
|
|
977
|
-
```
|
|
978
|
-
|
|
979
|
-
## Architecture
|
|
980
|
-
|
|
981
|
-
### Auto-Wrap System Architecture
|
|
982
|
-
|
|
983
|
-
```
|
|
984
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
985
|
-
│ User Workflow │
|
|
986
|
-
└──────────────────────────────────────────────────────────────┘
|
|
987
|
-
│
|
|
988
|
-
│ 1. Add servers with native command
|
|
989
|
-
│ (claude mcp add server ...)
|
|
990
|
-
▼
|
|
991
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
992
|
-
│ ~/.config/claude/config.json │
|
|
993
|
-
│ { │
|
|
994
|
-
│ "mcpServers": { │
|
|
995
|
-
│ "github": { │
|
|
996
|
-
│ "command": "npx", │
|
|
997
|
-
│ "args": ["-y", "@modelcontextprotocol/server-github"] │
|
|
998
|
-
│ } │
|
|
999
|
-
│ } │
|
|
1000
|
-
│ } │
|
|
1001
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1002
|
-
│
|
|
1003
|
-
│ 2. Run wrapper
|
|
1004
|
-
│ (mcp-gov-wrap --config ... --rules ... --tool ...)
|
|
1005
|
-
▼
|
|
1006
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
1007
|
-
│ mcp-gov-wrap │
|
|
1008
|
-
│ ┌────────────────────────────────────────────────────────┐ │
|
|
1009
|
-
│ │ 1. Read config file (detect format) │ │
|
|
1010
|
-
│ │ 2. Load rules from ~/.mcp-gov/rules.json │ │
|
|
1011
|
-
│ │ 3. Detect unwrapped servers │ │
|
|
1012
|
-
│ │ 4. Create timestamped backup │ │
|
|
1013
|
-
│ │ 5. Wrap servers: replace command with mcp-gov-proxy │ │
|
|
1014
|
-
│ │ 6. Execute tool command (e.g., "claude chat") │ │
|
|
1015
|
-
│ └────────────────────────────────────────────────────────┘ │
|
|
1016
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1017
|
-
│
|
|
1018
|
-
│ 3. Config now wrapped
|
|
1019
|
-
▼
|
|
1020
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
1021
|
-
│ ~/.config/claude/config.json (wrapped) │
|
|
1022
|
-
│ { │
|
|
1023
|
-
│ "mcpServers": { │
|
|
1024
|
-
│ "github": { │
|
|
1025
|
-
│ "command": "mcp-gov-proxy", │
|
|
1026
|
-
│ "args": [ │
|
|
1027
|
-
│ "--service", "github", │
|
|
1028
|
-
│ "--target", "npx -y @modelcontextprotocol/...", │
|
|
1029
|
-
│ "--rules", "/home/user/.mcp-gov/rules.json" │
|
|
1030
|
-
│ ] │
|
|
1031
|
-
│ } │
|
|
1032
|
-
│ } │
|
|
1033
|
-
│ } │
|
|
1034
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1035
|
-
│
|
|
1036
|
-
│ 4. Client launches with governed servers
|
|
1037
|
-
▼
|
|
1038
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
1039
|
-
│ MCP Client │
|
|
1040
|
-
│ (Claude Code, Droid, etc.) │
|
|
1041
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1042
|
-
│
|
|
1043
|
-
│ 5. Client makes tool call
|
|
1044
|
-
│ (tools/call: github_delete_repo)
|
|
1045
|
-
▼
|
|
1046
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
1047
|
-
│ mcp-gov-proxy │
|
|
1048
|
-
│ ┌────────────────────────────────────────────────────────┐ │
|
|
1049
|
-
│ │ JSON-RPC Message Interception │ │
|
|
1050
|
-
│ │ ↓ │ │
|
|
1051
|
-
│ │ Operation Detection │ │
|
|
1052
|
-
│ │ - Parse tool name: github_delete_repo │ │
|
|
1053
|
-
│ │ - Extract service: github │ │
|
|
1054
|
-
│ │ - Extract operation: delete │ │
|
|
1055
|
-
│ │ ↓ │ │
|
|
1056
|
-
│ │ Permission Check │ │
|
|
1057
|
-
│ │ - Load rules.json │ │
|
|
1058
|
-
│ │ - Check service="github", operation="delete" │ │
|
|
1059
|
-
│ │ - Decision: DENY │ │
|
|
1060
|
-
│ │ ↓ │ │
|
|
1061
|
-
│ │ Audit Logging (stderr) │ │
|
|
1062
|
-
│ │ {"timestamp":"...","tool":"github_delete_repo", │ │
|
|
1063
|
-
│ │ "service":"github","operation":"delete", │ │
|
|
1064
|
-
│ │ "status":"denied","reason":"..."} │ │
|
|
1065
|
-
│ │ ↓ │ │
|
|
1066
|
-
│ │ Response │ │
|
|
1067
|
-
│ │ - If ALLOW: Forward to target server │ │
|
|
1068
|
-
│ │ - If DENY: Return error to client │ │
|
|
1069
|
-
│ └────────────────────────────────────────────────────────┘ │
|
|
1070
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1071
|
-
│
|
|
1072
|
-
│ 6a. If ALLOWED: Forward to target
|
|
1073
|
-
▼
|
|
1074
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
1075
|
-
│ Target MCP Server │
|
|
1076
|
-
│ (npx -y @modelcontextprotocol/server-github) │
|
|
1077
|
-
│ ┌────────────────────────────────────────────────────────┐ │
|
|
1078
|
-
│ │ Execute tool logic │ │
|
|
1079
|
-
│ │ - Call GitHub API │ │
|
|
1080
|
-
│ │ - Return result │ │
|
|
1081
|
-
│ └────────────────────────────────────────────────────────┘ │
|
|
1082
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1083
|
-
│
|
|
1084
|
-
│ 7. Result flows back to client
|
|
1085
|
-
▼
|
|
1086
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
1087
|
-
│ MCP Client │
|
|
1088
|
-
│ Receives result or error │
|
|
1089
|
-
└──────────────────────────────────────────────────────────────┘
|
|
1090
|
-
```
|
|
1091
|
-
|
|
1092
|
-
### Component Responsibilities
|
|
1093
|
-
|
|
1094
|
-
**mcp-gov-wrap (Wrapper)**
|
|
1095
|
-
- Config file discovery and parsing
|
|
1096
|
-
- Server detection (wrapped vs unwrapped)
|
|
1097
|
-
- Automatic wrapping with mcp-gov-proxy
|
|
1098
|
-
- Config backup management
|
|
1099
|
-
- Tool command execution
|
|
1100
|
-
|
|
1101
|
-
**mcp-gov-proxy (Proxy)**
|
|
1102
|
-
- JSON-RPC message interception
|
|
1103
|
-
- Operation detection and classification
|
|
1104
|
-
- Permission checking against rules
|
|
1105
|
-
- Audit logging to stderr
|
|
1106
|
-
- Message forwarding to target servers
|
|
1107
|
-
|
|
1108
|
-
**rules.json**
|
|
1109
|
-
- Centralized governance policies
|
|
1110
|
-
- Service-specific operation rules
|
|
1111
|
-
- Allow/deny decisions with reasons
|
|
1112
|
-
- Hot-reloadable (no restart needed)
|
|
1113
|
-
|
|
1114
|
-
**Target MCP Servers**
|
|
1115
|
-
- Unchanged original servers
|
|
1116
|
-
- No code modifications needed
|
|
1117
|
-
- Work through proxy transparently
|
|
1118
|
-
|
|
1119
|
-
### Data Flow
|
|
1120
|
-
|
|
1121
|
-
1. **Setup**: User adds servers with native commands → mcp-gov-wrap wraps them
|
|
1122
|
-
2. **Runtime**: Client calls tool → Proxy intercepts → Checks permission → Forwards or denies
|
|
1123
|
-
3. **Audit**: Every operation logged to stderr with timestamp, service, operation, status
|
|
1124
|
-
4. **Updates**: Change rules.json → Takes effect immediately on next call
|
|
1125
|
-
|
|
1126
|
-
### Programmatic API Architecture (Alternative)
|
|
1127
|
-
|
|
1128
|
-
For building custom governed servers:
|
|
1129
|
-
|
|
1130
|
-
```
|
|
1131
|
-
┌─────────────────┐
|
|
1132
|
-
│ MCP Client │ (Claude Desktop)
|
|
1133
|
-
└────────┬────────┘
|
|
1134
|
-
│ MCP Protocol (stdio)
|
|
1135
|
-
▼
|
|
1136
|
-
┌─────────────────┐
|
|
1137
|
-
│ GovernedMCP │ 1. Check permission
|
|
1138
|
-
│ Server │ 2. Log operation
|
|
1139
|
-
│ (SDK) │ 3. Execute handler
|
|
1140
|
-
└────────┬────────┘
|
|
1141
|
-
│
|
|
1142
|
-
▼
|
|
1143
|
-
┌─────────────────┐
|
|
1144
|
-
│ Tool Handlers │ (GitHub API, etc.)
|
|
1145
|
-
└─────────────────┘
|
|
1146
|
-
```
|
|
1147
|
-
|
|
1148
|
-
## Examples
|
|
1149
|
-
|
|
1150
|
-
### Auto-Wrap System
|
|
1151
|
-
|
|
1152
|
-
- **[Auto-Wrap Example](examples/auto-wrap-example.md)**: Complete step-by-step walkthrough
|
|
1153
|
-
- Installation and setup
|
|
1154
|
-
- Creating rules files
|
|
1155
|
-
- Adding and wrapping servers
|
|
1156
|
-
- Daily workflow and monitoring
|
|
1157
|
-
|
|
1158
|
-
- **[Multi-Client Example](examples/multi-client-example.md)**: Using governance with multiple MCP clients
|
|
1159
|
-
- Claude Code, Droid, and custom clients
|
|
1160
|
-
- Shared rules across clients
|
|
1161
|
-
- Centralized audit logging
|
|
1162
|
-
- Environment-specific configurations
|
|
1163
|
-
|
|
1164
|
-
### Programmatic API
|
|
1165
|
-
|
|
1166
|
-
- **[GitHub Example](examples/github/)**: Complete working example with:
|
|
1167
|
-
- GitHub API integration (list repos, delete repo)
|
|
1168
|
-
- Permission rules configuration
|
|
1169
|
-
- Environment variable management
|
|
1170
|
-
- Claude Desktop integration
|
|
1171
|
-
|
|
1172
|
-
## Platform Compatibility
|
|
1173
|
-
|
|
1174
|
-
mcp-gov is designed to work seamlessly across Linux, macOS, and Windows. The system handles platform-specific path conventions and behaviors automatically.
|
|
1175
|
-
|
|
1176
|
-
### Supported Platforms
|
|
1177
|
-
|
|
1178
|
-
- **Linux**: Full support with Unix path separators (`/`) and LF line endings
|
|
1179
|
-
- **macOS**: Full support including .app bundles, case-sensitive filesystems, and system symlinks
|
|
1180
|
-
- **Windows**: Full support with drive letters (`C:\`), UNC paths (`\\server\share`), backslashes, and CRLF line endings
|
|
1181
|
-
|
|
1182
|
-
### Path Handling
|
|
1183
|
-
|
|
1184
|
-
The proxy and wrapper tools automatically handle platform-specific path formats:
|
|
1185
|
-
|
|
1186
|
-
**Linux/macOS:**
|
|
1187
|
-
```bash
|
|
1188
|
-
# Unix-style paths with forward slashes
|
|
1189
|
-
mcp-gov-proxy --target "node server.js" --rules /home/user/rules.json
|
|
1190
|
-
mcp-gov-wrap --config ~/.config/claude/config.json --rules ~/.mcp-gov/rules.json --tool "claude chat"
|
|
1191
|
-
```
|
|
1192
|
-
|
|
1193
|
-
**Windows:**
|
|
1194
|
-
```powershell
|
|
1195
|
-
# Windows-style paths with backslashes or forward slashes
|
|
1196
|
-
mcp-gov-proxy --target "node server.js" --rules C:\Users\user\rules.json
|
|
1197
|
-
mcp-gov-wrap --config %USERPROFILE%\.config\claude\config.json --rules %USERPROFILE%\.mcp-gov\rules.json --tool "claude chat"
|
|
1198
|
-
```
|
|
1199
|
-
|
|
1200
|
-
### Special Considerations
|
|
1201
|
-
|
|
1202
|
-
**macOS:**
|
|
1203
|
-
- Application bundles (`.app` directories) are handled correctly
|
|
1204
|
-
- System symlinks like `/tmp` → `/private/tmp` work transparently
|
|
1205
|
-
- Both case-sensitive and case-insensitive APFS filesystems are supported
|
|
1206
|
-
|
|
1207
|
-
**Windows:**
|
|
1208
|
-
- UNC network paths (`\\server\share\path`) are fully supported
|
|
1209
|
-
- Paths with spaces are handled correctly (e.g., `C:\Program Files`)
|
|
1210
|
-
- Both forward slashes and backslashes work in paths
|
|
1211
|
-
- Drive letters in absolute paths (e.g., `C:\`, `D:\`) are preserved
|
|
1212
|
-
|
|
1213
|
-
**Line Endings:**
|
|
1214
|
-
- Config files can use either LF (Unix/macOS) or CRLF (Windows) line endings
|
|
1215
|
-
- JSON parsing handles both formats automatically
|
|
1216
|
-
- Backup files preserve the original line ending format
|
|
1217
|
-
|
|
1218
|
-
### Testing
|
|
1219
|
-
|
|
1220
|
-
The test suite includes platform-specific test cases for Windows and macOS scenarios, even when run on Linux. To run platform tests:
|
|
1221
|
-
|
|
1222
|
-
```bash
|
|
1223
|
-
npm run test:platform
|
|
1224
|
-
```
|
|
1225
|
-
|
|
1226
|
-
These tests verify path handling, line ending compatibility, and platform-specific behaviors without requiring multiple operating systems for development.
|
|
1227
|
-
|
|
1228
|
-
## Development
|
|
1229
|
-
|
|
1230
|
-
```bash
|
|
1231
|
-
# Run all tests
|
|
1232
|
-
npm test
|
|
1233
|
-
|
|
1234
|
-
# Run specific test suites
|
|
1235
|
-
npm run test:proxy
|
|
1236
|
-
npm run test:wrapper
|
|
1237
|
-
npm run test:platform
|
|
1238
|
-
npm run test:integration
|
|
1239
|
-
|
|
1240
|
-
# Test operation detection
|
|
1241
|
-
node -e "import('./src/operation-detector.js').then(m => console.log(m.detectOperation('github_list_repos')))"
|
|
1242
|
-
|
|
1243
|
-
# Test permission checking
|
|
1244
|
-
node -e "import('./src/index.js').then(m => {
|
|
1245
|
-
const s = new m.GovernedMCPServer({name:'test',version:'1.0'}, {github:{delete:'deny'}});
|
|
1246
|
-
console.log(s.checkPermission('github_delete_repo'));
|
|
1247
|
-
})"
|
|
122
|
+
# Low-level proxy (used internally)
|
|
123
|
+
mcp-gov-proxy --service github --target "npx server" --rules ~/.mcp-gov/rules.json
|
|
1248
124
|
```
|
|
1249
125
|
|
|
1250
126
|
## License
|
|
1251
127
|
|
|
1252
128
|
MIT
|
|
1253
|
-
|
|
1254
|
-
## Contributing
|
|
1255
|
-
|
|
1256
|
-
Contributions welcome! Please open an issue or PR.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-gov",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.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",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"bin/",
|
|
30
30
|
"src/",
|
|
31
31
|
"postinstall.js",
|
|
32
|
-
"README.md"
|
|
32
|
+
"README.md",
|
|
33
|
+
"CHANGELOG.md"
|
|
33
34
|
],
|
|
34
35
|
"repository": {
|
|
35
36
|
"type": "git",
|