mcpmon 0.1.4 → 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.
- package/.github/workflows/release.yml +37 -17
- package/.nojekyll +0 -0
- package/.pre-commit-config.yaml +44 -0
- package/README.md +121 -19
- package/__main__.py +6 -0
- package/bun.lock +15 -0
- package/gateway.ts +581 -0
- package/index.html +557 -0
- package/mcpmon/__init__.py +355 -0
- package/mcpmon/__main__.py +6 -0
- package/mcpmon/config.py +101 -0
- package/mcpmon/gateway.py +529 -0
- package/mcpmon/log.py +84 -0
- package/mcpmon.test.ts +568 -0
- package/mcpmon.ts +270 -33
- package/package.json +4 -1
- package/pyproject.toml +12 -1
- package/tests/__init__.py +1 -0
- package/tests/test_gateway.py +403 -0
- package/tests/test_mcpmon.py +644 -0
- package/tests/test_new_tool_server.py +209 -0
- package/.github/.tmp/.generated-actions/run-pypi-publish-in-docker-container/action.yml +0 -1
- package/dist/mcpmon-0.1.4-py3-none-any.whl +0 -0
- package/dist/mcpmon-0.1.4-py3-none-any.whl.publish.attestation +0 -1
- package/dist/mcpmon-0.1.4.tar.gz +0 -0
- package/dist/mcpmon-0.1.4.tar.gz.publish.attestation +0 -1
- package/mcpmon.py +0 -112
|
@@ -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
|
-
|
|
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
|
-
|
|
76
|
-
run: gh release create "v$
|
|
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:
|
|
118
|
+
needs: publish
|
|
97
119
|
runs-on: ${{ matrix.os }}
|
|
98
120
|
permissions:
|
|
99
121
|
contents: write
|
|
@@ -104,12 +126,10 @@ jobs:
|
|
|
104
126
|
target: linux-x64
|
|
105
127
|
- os: macos-latest
|
|
106
128
|
target: darwin-arm64
|
|
107
|
-
- os: macos-
|
|
129
|
+
- os: macos-15-intel
|
|
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.
|
|
146
|
+
VERSION: ${{ needs.publish.outputs.version }}
|
|
127
147
|
TARGET: ${{ matrix.target }}
|
|
128
148
|
run: gh release upload "v$VERSION" "mcpmon-$TARGET" --clobber
|
package/.nojekyll
ADDED
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# .pre-commit-config.yaml
|
|
3
|
+
# Install: pip install pre-commit && pre-commit install
|
|
4
|
+
# Run manually: pre-commit run --all-files
|
|
5
|
+
# ============================================================================
|
|
6
|
+
|
|
7
|
+
repos:
|
|
8
|
+
# -------------------------------------------------------------------------
|
|
9
|
+
# SECRET DETECTION
|
|
10
|
+
# -------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
13
|
+
rev: v8.18.1
|
|
14
|
+
hooks:
|
|
15
|
+
- id: gitleaks
|
|
16
|
+
name: Detect secrets with gitleaks
|
|
17
|
+
|
|
18
|
+
# -------------------------------------------------------------------------
|
|
19
|
+
# GENERAL
|
|
20
|
+
# -------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
23
|
+
rev: v4.5.0
|
|
24
|
+
hooks:
|
|
25
|
+
- id: trailing-whitespace
|
|
26
|
+
- id: end-of-file-fixer
|
|
27
|
+
- id: check-yaml
|
|
28
|
+
- id: check-json
|
|
29
|
+
- id: check-toml
|
|
30
|
+
- id: check-added-large-files
|
|
31
|
+
args: ['--maxkb=500']
|
|
32
|
+
- id: detect-private-key
|
|
33
|
+
- id: detect-aws-credentials
|
|
34
|
+
|
|
35
|
+
# -------------------------------------------------------------------------
|
|
36
|
+
# PYTHON
|
|
37
|
+
# -------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
40
|
+
rev: v0.3.0
|
|
41
|
+
hooks:
|
|
42
|
+
- id: ruff
|
|
43
|
+
args: [--fix]
|
|
44
|
+
- id: ruff-format
|
package/README.md
CHANGED
|
@@ -2,51 +2,115 @@
|
|
|
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
|
-
#
|
|
9
|
-
|
|
15
|
+
# Python
|
|
16
|
+
pip install mcpmon
|
|
10
17
|
|
|
11
|
-
#
|
|
12
|
-
|
|
18
|
+
# Bun (no install needed)
|
|
19
|
+
bunx mcpmon
|
|
13
20
|
|
|
14
|
-
#
|
|
15
|
-
|
|
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
|
-
###
|
|
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
|
|
62
|
+
|
|
63
|
+
| Option | Description |
|
|
64
|
+
|--------|-------------|
|
|
65
|
+
| `-c, --config <file>` | Config file for multi-server gateway mode |
|
|
66
|
+
| `-w, --watch <dir>` | Directory to watch (default: `.`) |
|
|
67
|
+
| `-e, --ext <exts>` | Extensions to watch, comma-separated (default: `py`) |
|
|
68
|
+
| `-q, --quiet` | Only show errors |
|
|
69
|
+
| `-v, --verbose` | Show file change details |
|
|
70
|
+
| `--debug` | Show all debug output |
|
|
71
|
+
| `-t, --timestamps` | Include timestamps in output |
|
|
72
|
+
| `-l, --log-file <file>` | Also write logs to file |
|
|
27
73
|
|
|
28
|
-
|
|
29
|
-
- `--ext, -e` - File extensions to watch, comma-separated (default: py)
|
|
74
|
+
### Logging Levels
|
|
30
75
|
|
|
31
|
-
|
|
76
|
+
```
|
|
77
|
+
--quiet Only errors
|
|
78
|
+
(default) Start, stop, restart events + PID
|
|
79
|
+
--verbose + file change details
|
|
80
|
+
--debug + everything
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Examples
|
|
32
84
|
|
|
33
85
|
```bash
|
|
34
|
-
#
|
|
86
|
+
# Basic - watch current directory for .py changes
|
|
35
87
|
mcpmon -- python server.py
|
|
36
88
|
|
|
37
|
-
# Watch
|
|
89
|
+
# Watch specific directory and extensions
|
|
38
90
|
mcpmon --watch src/ --ext py,json -- python -m myserver
|
|
39
91
|
|
|
40
|
-
# With
|
|
41
|
-
mcpmon --
|
|
92
|
+
# With timestamps and log file
|
|
93
|
+
mcpmon --timestamps --log-file mcpmon.log -- python server.py
|
|
94
|
+
|
|
95
|
+
# Gateway mode - multiple servers
|
|
96
|
+
mcpmon --config .mcpmon.yaml
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Sample Output
|
|
42
100
|
|
|
43
|
-
|
|
44
|
-
mcpmon
|
|
101
|
+
```
|
|
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
|
|
105
|
+
[mcpmon 16:08:54 pid:53307] Restarting...
|
|
106
|
+
[mcpmon 16:08:54 pid:53411] Started: python -m my_server
|
|
107
|
+
[mcpmon 16:08:54 pid:53411] Restart #1 complete
|
|
108
|
+
[mcpmon 16:08:54] Sent tools/list_changed notification
|
|
45
109
|
```
|
|
46
110
|
|
|
47
111
|
## MCP Config
|
|
48
112
|
|
|
49
|
-
|
|
113
|
+
### Single Server
|
|
50
114
|
|
|
51
115
|
```json
|
|
52
116
|
{
|
|
@@ -59,9 +123,47 @@ Use mcpmon in your `.mcp.json` for hot reload during development:
|
|
|
59
123
|
}
|
|
60
124
|
```
|
|
61
125
|
|
|
62
|
-
|
|
126
|
+
### Gateway (Multiple Servers)
|
|
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
|
|
63
140
|
|
|
141
|
+
### Single Server Mode
|
|
64
142
|
1. Starts your MCP server as a subprocess
|
|
65
143
|
2. Watches specified directory for file changes
|
|
66
144
|
3. On change: SIGTERM → wait 2s → SIGKILL → restart
|
|
67
|
-
4.
|
|
145
|
+
4. Sends `notifications/tools/list_changed` notification
|
|
146
|
+
5. Claude Code refreshes tool cache automatically
|
|
147
|
+
|
|
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
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Python
|
|
160
|
+
pip install -e ".[dev]"
|
|
161
|
+
pytest tests/ -v # 42 tests
|
|
162
|
+
|
|
163
|
+
# Bun/TypeScript
|
|
164
|
+
bun test # 16 tests
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT
|
package/__main__.py
ADDED
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
|
+
}
|