mcpmon 0.3.0 → 1.0.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.
@@ -1,6 +1,9 @@
1
1
  name: Release
2
2
 
3
3
  on:
4
+ push:
5
+ tags:
6
+ - 'v*'
4
7
  workflow_dispatch:
5
8
  inputs:
6
9
  bump:
@@ -14,26 +17,20 @@ on:
14
17
  - major
15
18
 
16
19
  jobs:
17
- release:
20
+ # Only runs on workflow_dispatch - bumps version and creates tag
21
+ bump:
22
+ if: github.event_name == 'workflow_dispatch'
18
23
  runs-on: ubuntu-latest
19
24
  permissions:
20
25
  contents: write
21
- id-token: write
22
- outputs:
23
- version: ${{ steps.bump.outputs.version }}
24
26
  steps:
25
27
  - uses: actions/checkout@v4
26
28
  with:
27
29
  fetch-depth: 0
28
30
 
29
- - uses: actions/setup-python@v5
30
- with:
31
- python-version: "3.12"
32
-
33
31
  - uses: actions/setup-node@v4
34
32
  with:
35
33
  node-version: '20'
36
- # NOTE: No registry-url - npm OIDC trusted publishers require no auth token present
37
34
 
38
35
  - name: Get current version
39
36
  id: current
@@ -56,6 +53,7 @@ jobs:
56
53
  NEW_VERSION="$major.$minor.$patch"
57
54
  echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
58
55
  sed -i "s/version = \"$CURRENT_VERSION\"/version = \"$NEW_VERSION\"/" pyproject.toml
56
+ sed -i "s/__version__ = \"$CURRENT_VERSION\"/__version__ = \"$NEW_VERSION\"/" mcpmon/__init__.py || true
59
57
  npm version "$NEW_VERSION" --no-git-tag-version
60
58
 
61
59
  - name: Commit and tag
@@ -64,16 +62,40 @@ jobs:
64
62
  run: |
65
63
  git config user.name "github-actions[bot]"
66
64
  git config user.email "github-actions[bot]@users.noreply.github.com"
67
- git add pyproject.toml package.json
65
+ git add pyproject.toml package.json mcpmon/__init__.py
68
66
  git commit -m "(release): v$NEW_VERSION"
69
67
  git tag "v$NEW_VERSION"
70
68
  git push && git push --tags
71
69
 
70
+ # Runs on tag push - publishes to PyPI and npm
71
+ publish:
72
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
73
+ runs-on: ubuntu-latest
74
+ permissions:
75
+ contents: write
76
+ id-token: write
77
+ outputs:
78
+ version: ${{ steps.version.outputs.version }}
79
+ steps:
80
+ - uses: actions/checkout@v4
81
+
82
+ - name: Extract version from tag
83
+ id: version
84
+ run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
85
+
86
+ - uses: actions/setup-python@v5
87
+ with:
88
+ python-version: "3.12"
89
+
90
+ - uses: actions/setup-node@v4
91
+ with:
92
+ node-version: '20'
93
+
72
94
  - name: Create release
73
95
  env:
74
96
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75
- NEW_VERSION: ${{ steps.bump.outputs.version }}
76
- run: gh release create "v$NEW_VERSION" --generate-notes
97
+ VERSION: ${{ steps.version.outputs.version }}
98
+ run: gh release create "v$VERSION" --generate-notes || true
77
99
 
78
100
  # Publish to PyPI
79
101
  - name: Install build
@@ -93,7 +115,7 @@ jobs:
93
115
  run: npm publish --provenance --access public
94
116
 
95
117
  build-binaries:
96
- needs: release
118
+ needs: publish
97
119
  runs-on: ${{ matrix.os }}
98
120
  permissions:
99
121
  contents: write
@@ -108,8 +130,6 @@ jobs:
108
130
  target: darwin-x64
109
131
  steps:
110
132
  - uses: actions/checkout@v4
111
- with:
112
- ref: v${{ needs.release.outputs.version }}
113
133
 
114
134
  - uses: oven-sh/setup-bun@v2
115
135
  with:
@@ -123,6 +143,6 @@ jobs:
123
143
  - name: Upload to release
124
144
  env:
125
145
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
126
- VERSION: ${{ needs.release.outputs.version }}
146
+ VERSION: ${{ needs.publish.outputs.version }}
127
147
  TARGET: ${{ matrix.target }}
128
148
  run: gh release upload "v$VERSION" "mcpmon-$TARGET" --clobber
package/README.md CHANGED
@@ -2,31 +2,67 @@
2
2
 
3
3
  Hot reload for MCP servers. Like nodemon, but for MCP.
4
4
 
5
+ ## Features
6
+
7
+ - **Hot reload** - Restart server on file changes
8
+ - **Tool refresh** - Sends `notifications/tools/list_changed` so Claude Code sees new tools without session restart
9
+ - **Gateway mode** - Aggregate multiple MCP servers behind one gateway
10
+ - **Dual implementation** - Python and Bun/TypeScript with full feature parity
11
+
5
12
  ## Install
6
13
 
7
14
  ```bash
8
- # Bun (recommended)
9
- bunx mcpmon
15
+ # Python
16
+ pip install mcpmon
10
17
 
11
- # Or install globally
12
- bun install -g mcpmon
18
+ # Bun (no install needed)
19
+ bunx mcpmon
13
20
 
14
- # Python alternative
15
- pip install mcpmon
21
+ # npm
22
+ npm install -g mcpmon
16
23
 
17
24
  # Or download binary from GitHub releases (no dependencies)
18
25
  ```
19
26
 
20
27
  ## Usage
21
28
 
29
+ ### Single Server Mode
30
+
22
31
  ```bash
23
32
  mcpmon --watch src/ -- python -m my_mcp_server
24
33
  ```
25
34
 
26
- ### Options
35
+ ### Gateway Mode (Multi-Server)
36
+
37
+ ```bash
38
+ mcpmon --config .mcpmon.yaml
39
+ ```
40
+
41
+ ```yaml
42
+ # .mcpmon.yaml
43
+ servers:
44
+ sage:
45
+ command: sage-mcp
46
+ watch: ~/.sage/src/
47
+
48
+ crucible:
49
+ command: crucible-mcp
50
+ watch: ~/crucible/src/
51
+
52
+ my-server:
53
+ command: python
54
+ args: ["-m", "my_server"]
55
+ watch: ./src/
56
+ extensions: py,json
57
+ ```
58
+
59
+ Gateway aggregates tools with prefixes: `sage__recall`, `crucible__review`, etc.
60
+
61
+ ## Options
27
62
 
28
63
  | Option | Description |
29
64
  |--------|-------------|
65
+ | `-c, --config <file>` | Config file for multi-server gateway mode |
30
66
  | `-w, --watch <dir>` | Directory to watch (default: `.`) |
31
67
  | `-e, --ext <exts>` | Extensions to watch, comma-separated (default: `py`) |
32
68
  | `-q, --quiet` | Only show errors |
@@ -41,46 +77,40 @@ mcpmon --watch src/ -- python -m my_mcp_server
41
77
  --quiet Only errors
42
78
  (default) Start, stop, restart events + PID
43
79
  --verbose + file change details
44
- --debug + everything (ignored files, spawning, exit codes)
80
+ --debug + everything
45
81
  ```
46
82
 
47
- ### Examples
83
+ ## Examples
48
84
 
49
85
  ```bash
50
- # Basic usage - watch current directory for .py changes
86
+ # Basic - watch current directory for .py changes
51
87
  mcpmon -- python server.py
52
88
 
53
- # Watch src/ for .py and .json changes
89
+ # Watch specific directory and extensions
54
90
  mcpmon --watch src/ --ext py,json -- python -m myserver
55
91
 
56
- # With timestamps and verbose output
57
- mcpmon --timestamps --verbose -- python server.py
58
-
59
- # Log to file for debugging
60
- mcpmon --debug --log-file mcpmon.log -- python server.py
61
-
62
- # With crucible-mcp
63
- mcpmon --watch src/crucible/ -- crucible-mcp
92
+ # With timestamps and log file
93
+ mcpmon --timestamps --log-file mcpmon.log -- python server.py
64
94
 
65
- # With sage-mcp
66
- mcpmon --watch sage/ --ext py -- python -m sage.mcp_server
95
+ # Gateway mode - multiple servers
96
+ mcpmon --config .mcpmon.yaml
67
97
  ```
68
98
 
69
99
  ### Sample Output
70
100
 
71
101
  ```
72
- [mcpmon 16:08:50] Watching sage for .py changes
73
- [mcpmon 16:08:50 pid:53307] Started: python -m sage.mcp_server
102
+ [mcpmon 16:08:50] Watching src/ for .py changes
103
+ [mcpmon 16:08:50 pid:53307] Started: python -m my_server
104
+ [mcpmon 16:08:54] File modified: tools.py
74
105
  [mcpmon 16:08:54 pid:53307] Restarting...
75
- [mcpmon 16:08:54 pid:53411] Started: python -m sage.mcp_server
106
+ [mcpmon 16:08:54 pid:53411] Started: python -m my_server
76
107
  [mcpmon 16:08:54 pid:53411] Restart #1 complete
77
- [mcpmon 16:08:57] Received SIGTERM, shutting down...
78
- [mcpmon 16:08:57] Shutdown complete (restarts: 1)
108
+ [mcpmon 16:08:54] Sent tools/list_changed notification
79
109
  ```
80
110
 
81
111
  ## MCP Config
82
112
 
83
- Use mcpmon in your `.mcp.json` for hot reload during development:
113
+ ### Single Server
84
114
 
85
115
  ```json
86
116
  {
@@ -93,30 +123,47 @@ Use mcpmon in your `.mcp.json` for hot reload during development:
93
123
  }
94
124
  ```
95
125
 
96
- ## How it works
126
+ ### Gateway (Multiple Servers)
97
127
 
128
+ ```json
129
+ {
130
+ "mcpServers": {
131
+ "gateway": {
132
+ "command": "mcpmon",
133
+ "args": ["--config", ".mcpmon.yaml"]
134
+ }
135
+ }
136
+ }
137
+ ```
138
+
139
+ ## How It Works
140
+
141
+ ### Single Server Mode
98
142
  1. Starts your MCP server as a subprocess
99
143
  2. Watches specified directory for file changes
100
144
  3. On change: SIGTERM → wait 2s → SIGKILL → restart
101
- 4. Claude Code automatically reconnects to the restarted server
102
-
103
- ## Dual Implementation
104
-
105
- mcpmon ships as both:
106
- - **Bun/TypeScript** (`mcpmon.ts`) - Zero dependencies, fast startup
107
- - **Python** (`mcpmon.py`) - Uses `watchfiles` for robust file watching
145
+ 4. Sends `notifications/tools/list_changed` notification
146
+ 5. Claude Code refreshes tool cache automatically
108
147
 
109
- Both implementations have feature parity.
148
+ ### Gateway Mode
149
+ 1. Reads config file, starts all backend servers
150
+ 2. Aggregates tools from all backends (prefixed: `backend__tool`)
151
+ 3. Routes tool calls to correct backend
152
+ 4. Watches each backend's files independently
153
+ 5. Hot-reloads individual backends on change
154
+ 6. Hot-adds/removes backends when config changes
110
155
 
111
156
  ## Development
112
157
 
113
158
  ```bash
114
- # Install dev dependencies (Python)
159
+ # Python
115
160
  pip install -e ".[dev]"
161
+ pytest tests/ -v # 42 tests
116
162
 
117
- # Run Python tests (27 tests)
118
- pytest tests/ -v
119
-
120
- # Run Bun/TS tests (12 tests)
121
- bun test
163
+ # Bun/TypeScript
164
+ bun test # 16 tests
122
165
  ```
166
+
167
+ ## License
168
+
169
+ MIT
package/bun.lock ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "mcpmon",
7
+ "dependencies": {
8
+ "yaml": "^2.8.2",
9
+ },
10
+ },
11
+ },
12
+ "packages": {
13
+ "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="],
14
+ }
15
+ }