mcp-plugin 0.1.1__tar.gz

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.
@@ -0,0 +1,245 @@
1
+ # Runtime config — personal per-user settings; template is slife.template.json5.
2
+ slife.json5
3
+ mcp-plugin.json5
4
+
5
+ # Playwright MCP browser traces (test artifacts)
6
+ .playwright-mcp/
7
+
8
+ # Credential store encrypted backup
9
+ credentials.crypt
10
+
11
+ # WeChat session files (contain auth tokens)
12
+ wechat_*.json5
13
+
14
+ # Runtime logs
15
+ logs/
16
+
17
+ # User-saved files (memfiles plugin storage — per-agent runtime data)
18
+ *.files/
19
+
20
+ # Byte-compiled / optimized / DLL files
21
+ __pycache__/
22
+ *.py[codz]
23
+ *$py.class
24
+
25
+ # C extensions
26
+ *.so
27
+
28
+ # Distribution / packaging
29
+ .Python
30
+ build/
31
+ develop-eggs/
32
+ dist/
33
+ downloads/
34
+ eggs/
35
+ .eggs/
36
+ lib/
37
+ lib64/
38
+ parts/
39
+ sdist/
40
+ var/
41
+ wheels/
42
+ share/python-wheels/
43
+ *.egg-info/
44
+ .installed.cfg
45
+ *.egg
46
+ MANIFEST
47
+
48
+ # PyInstaller
49
+ # Usually these files are written by a python script from a template
50
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
51
+ *.manifest
52
+ *.spec
53
+
54
+ # Installer logs
55
+ pip-log.txt
56
+ pip-delete-this-directory.txt
57
+
58
+ # Unit test / coverage reports
59
+ htmlcov/
60
+ .tox/
61
+ .nox/
62
+ .coverage
63
+ .coverage.*
64
+ .cache
65
+ nosetests.xml
66
+ coverage.xml
67
+ *.cover
68
+ *.py.cover
69
+ .hypothesis/
70
+ .pytest_cache/
71
+ cover/
72
+
73
+ # Translations
74
+ *.mo
75
+ *.pot
76
+
77
+ # Django stuff:
78
+ *.log
79
+ local_settings.py
80
+ db.sqlite3
81
+ db.sqlite3-journal
82
+
83
+ # Flask stuff:
84
+ instance/
85
+ .webassets-cache
86
+
87
+ # Scrapy stuff:
88
+ .scrapy
89
+
90
+ # Sphinx documentation
91
+ docs/_build/
92
+
93
+ # PyBuilder
94
+ .pybuilder/
95
+ target/
96
+
97
+ # Jupyter Notebook
98
+ .ipynb_checkpoints
99
+
100
+ # IPython
101
+ profile_default/
102
+ ipython_config.py
103
+
104
+ # pyenv
105
+ # For a library or package, you might want to ignore these files since the code is
106
+ # intended to run in multiple environments; otherwise, check them in:
107
+ # .python-version
108
+
109
+ # pipenv
110
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
111
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
112
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
113
+ # install all needed dependencies.
114
+ # Pipfile.lock
115
+
116
+ # UV
117
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
118
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
119
+ # commonly ignored for libraries.
120
+ # uv.lock
121
+
122
+ # poetry
123
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
124
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
125
+ # commonly ignored for libraries.
126
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
127
+ # poetry.lock
128
+ # poetry.toml
129
+
130
+ # pdm
131
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
132
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
133
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
134
+ # pdm.lock
135
+ # pdm.toml
136
+ .pdm-python
137
+ .pdm-build/
138
+
139
+ # pixi
140
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
141
+ # pixi.lock
142
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
143
+ # in the .venv directory. It is recommended not to include this directory in version control.
144
+ .pixi
145
+
146
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
147
+ __pypackages__/
148
+
149
+ # Celery stuff
150
+ celerybeat-schedule
151
+ celerybeat.pid
152
+
153
+ # Redis
154
+ *.rdb
155
+ *.aof
156
+ *.pid
157
+
158
+ # RabbitMQ
159
+ mnesia/
160
+ rabbitmq/
161
+ rabbitmq-data/
162
+
163
+ # ActiveMQ
164
+ activemq-data/
165
+
166
+ # SageMath parsed files
167
+ *.sage.py
168
+
169
+ # Environments
170
+ .env
171
+ .envrc
172
+ .venv
173
+ env/
174
+ venv/
175
+ ENV/
176
+ env.bak/
177
+ venv.bak/
178
+
179
+ # Spyder project settings
180
+ .spyderproject
181
+ .spyproject
182
+
183
+ # Rope project settings
184
+ .ropeproject
185
+
186
+ # mkdocs documentation
187
+ /site
188
+
189
+ # mypy
190
+ .mypy_cache/
191
+ .dmypy.json
192
+ dmypy.json
193
+
194
+ # Pyre type checker
195
+ .pyre/
196
+
197
+ # pytype static type analyzer
198
+ .pytype/
199
+
200
+ # Cython debug symbols
201
+ cython_debug/
202
+
203
+ # PyCharm
204
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
205
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
206
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
207
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
208
+ # .idea/
209
+
210
+ # Abstra
211
+ # Abstra is an AI-powered process automation framework.
212
+ # Ignore directories containing user credentials, local state, and settings.
213
+ # Learn more at https://abstra.io/docs
214
+ .abstra/
215
+
216
+ # Visual Studio Code
217
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
218
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
219
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
220
+ # you could uncomment the following to ignore the entire vscode folder
221
+ # .vscode/
222
+ # Temporary file for partial code execution
223
+ tempCodeRunnerFile.py
224
+
225
+ # Ruff stuff:
226
+ .ruff_cache/
227
+
228
+ # PyPI configuration file
229
+ .pypirc
230
+
231
+ # Marimo
232
+ marimo/_static/
233
+ marimo/_lsp/
234
+ __marimo__/
235
+
236
+ # Streamlit
237
+ .streamlit/secrets.toml
238
+
239
+ # SQLite database files (may appear anywhere in the project)
240
+ *.db
241
+ *.db-shm
242
+ *.db-wal
243
+
244
+ # local DB backups (never committed)
245
+ slife.db.bak*
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.3
2
+ Name: mcp-plugin
3
+ Version: 0.1.1
4
+ Summary: Standalone MCP gateway — persistent connections to external MCP servers
5
+ Project-URL: Homepage, https://github.com/juzcn/slife
6
+ Project-URL: Repository, https://github.com/juzcn/slife
7
+ Project-URL: Documentation, https://github.com/juzcn/slife/blob/main/mcp-plugin/README.md
8
+ Author-email: juzcn <zhangjun@cueb.edu.cn>
9
+ License: MIT
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Terminals
17
+ Requires-Python: >=3.13
18
+ Requires-Dist: credstore
19
+ Requires-Dist: fastmcp>=2.0.0
20
+ Requires-Dist: httpx>=0.27.0
21
+ Requires-Dist: json5>=0.15.0
22
+ Requires-Dist: mcp>=1.0.0
23
+ Description-Content-Type: text/markdown
24
+
25
+ # mcp-plugin
26
+
27
+ Standalone MCP gateway — persistent connections to external MCP servers, with a
28
+ CLI to configure and test them. Ships with [Slife](https://github.com/juzcn/slife)
29
+ as its built-in MCP plugin but has **no dependency on it**. Depends only on
30
+ `fastmcp`, `mcp`, `httpx`, `json5`, and `credstore` (for OAuth token storage).
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ pip install mcp-plugin
36
+ # or bundled with Slife:
37
+ uv tool install git+https://github.com/juzcn/slife.git
38
+ ```
39
+
40
+ Verify: `mcp-plugin`
41
+
42
+ ## Config
43
+
44
+ Server definitions live in `mcp-plugin.json5`, located by precedence:
45
+
46
+ 1. `MCP_PLUGIN_FILE=<path>` (env var — Slife exports this to the same directory
47
+ as `slife.json5` when it launches the plugin)
48
+ 2. `./mcp-plugin.json5` (dev — when the current directory is the Slife source
49
+ root, i.e. its `pyproject.toml` has `project.name == "slife"`)
50
+ 3. `~/.mcp-plugin/mcp-plugin.json5` (default, standalone use)
51
+
52
+ This is the same resolution credstore uses for its `credentials.crypt`.
53
+
54
+ Keys in `env` and `auth.client_id`/`client_secret` support these references,
55
+ resolved in order **shell env → credstore → literal**:
56
+
57
+ ```json5
58
+ // mcp-plugin.json5
59
+ {
60
+ servers: {
61
+ filesystem: {
62
+ enabled: false, // optional; absent = enabled
63
+ command: "npx",
64
+ args: [
65
+ "-y",
66
+ "@modelcontextprotocol/server-filesystem",
67
+ "."
68
+ ],
69
+ },
70
+ github: {
71
+ command: "npx",
72
+ args: [
73
+ "-y",
74
+ "anyapi-mcp-server",
75
+ "--name", "github",
76
+ "--spec", "https://api.github.com/github-raml",
77
+ "--base-url", "https://api.github.com",
78
+ "--header", "Authorization: Bearer ${GITHUB_TOKEN}",
79
+ ],
80
+ },
81
+ remote: {
82
+ url: "https://example.com/mcp",
83
+ headers: { Authorization: "Bearer ${REMOTE_TOKEN}" },
84
+ auth: { type: "oauth", client_id: "${OAUTH_CLIENT_ID}" },
85
+ },
86
+ },
87
+ }
88
+ ```
89
+
90
+ ## CLI
91
+
92
+ | Command | Description |
93
+ |---------|-------------|
94
+ | `mcp-plugin` | Overview of configured servers |
95
+ | `mcp-plugin set <server>` | Interactive add/configure a server |
96
+ | `mcp-plugin remove <server>` | Remove a server from config (takes effect at next server start) |
97
+ | `mcp-plugin test [--port N]` | Start the real plugin server and verify it serves MCP; show the auto-connected servers |
98
+ | `mcp-plugin test mcp <server>` | Bare-connect to one server (no framework) + list its tools |
99
+
100
+ `set` accepts `--transport stdio|http`, `--command`, `--url`, `--args`,
101
+ `--env` (`KEY=VALUE`), `--enabled/--no-enabled`, and `--auth oauth` prompts.
102
+
103
+ ### Testing
104
+
105
+ `mcp-plugin test` verifies the plugin itself end-to-end: it spawns the real
106
+ plugin server (`python -m mcp_plugin.server` — the same entry Slife launches),
107
+ reads its `{"port": N}` ready signal, connects over Streamable HTTP, checks the
108
+ management tools are served, and reports the external servers the plugin
109
+ auto-connected. `--port N` pins the server's port instead of auto-assigning.
110
+
111
+ `mcp-plugin test mcp <server>` is the opposite check — it bare-connects to one
112
+ external MCP server using the raw `mcp` SDK (no plugin framework), confirms it
113
+ speaks MCP, and lists its tools.
114
+
115
+ ## Plugin contract
116
+
117
+ An MCP-plugin distribution exposes a module that hosts its own FastMCP server
118
+ (transport: streamable HTTP on an auto-assigned port, port signaled to stdout as
119
+ `{"port": N}`). Slife discovers it via `plugins.external` in `slife.json5` and
120
+ spawns `python -m <module>`. The management tools (`mcp_set`, `mcp_remove`,
121
+ `mcp_set_enabled`, `mcp_list`, `mcp_list_tools`, `__mcp_call_tool`,
122
+ `__mcp_connection_status`) are kept separate from the servers they manage.
@@ -0,0 +1,98 @@
1
+ # mcp-plugin
2
+
3
+ Standalone MCP gateway — persistent connections to external MCP servers, with a
4
+ CLI to configure and test them. Ships with [Slife](https://github.com/juzcn/slife)
5
+ as its built-in MCP plugin but has **no dependency on it**. Depends only on
6
+ `fastmcp`, `mcp`, `httpx`, `json5`, and `credstore` (for OAuth token storage).
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ pip install mcp-plugin
12
+ # or bundled with Slife:
13
+ uv tool install git+https://github.com/juzcn/slife.git
14
+ ```
15
+
16
+ Verify: `mcp-plugin`
17
+
18
+ ## Config
19
+
20
+ Server definitions live in `mcp-plugin.json5`, located by precedence:
21
+
22
+ 1. `MCP_PLUGIN_FILE=<path>` (env var — Slife exports this to the same directory
23
+ as `slife.json5` when it launches the plugin)
24
+ 2. `./mcp-plugin.json5` (dev — when the current directory is the Slife source
25
+ root, i.e. its `pyproject.toml` has `project.name == "slife"`)
26
+ 3. `~/.mcp-plugin/mcp-plugin.json5` (default, standalone use)
27
+
28
+ This is the same resolution credstore uses for its `credentials.crypt`.
29
+
30
+ Keys in `env` and `auth.client_id`/`client_secret` support these references,
31
+ resolved in order **shell env → credstore → literal**:
32
+
33
+ ```json5
34
+ // mcp-plugin.json5
35
+ {
36
+ servers: {
37
+ filesystem: {
38
+ enabled: false, // optional; absent = enabled
39
+ command: "npx",
40
+ args: [
41
+ "-y",
42
+ "@modelcontextprotocol/server-filesystem",
43
+ "."
44
+ ],
45
+ },
46
+ github: {
47
+ command: "npx",
48
+ args: [
49
+ "-y",
50
+ "anyapi-mcp-server",
51
+ "--name", "github",
52
+ "--spec", "https://api.github.com/github-raml",
53
+ "--base-url", "https://api.github.com",
54
+ "--header", "Authorization: Bearer ${GITHUB_TOKEN}",
55
+ ],
56
+ },
57
+ remote: {
58
+ url: "https://example.com/mcp",
59
+ headers: { Authorization: "Bearer ${REMOTE_TOKEN}" },
60
+ auth: { type: "oauth", client_id: "${OAUTH_CLIENT_ID}" },
61
+ },
62
+ },
63
+ }
64
+ ```
65
+
66
+ ## CLI
67
+
68
+ | Command | Description |
69
+ |---------|-------------|
70
+ | `mcp-plugin` | Overview of configured servers |
71
+ | `mcp-plugin set <server>` | Interactive add/configure a server |
72
+ | `mcp-plugin remove <server>` | Remove a server from config (takes effect at next server start) |
73
+ | `mcp-plugin test [--port N]` | Start the real plugin server and verify it serves MCP; show the auto-connected servers |
74
+ | `mcp-plugin test mcp <server>` | Bare-connect to one server (no framework) + list its tools |
75
+
76
+ `set` accepts `--transport stdio|http`, `--command`, `--url`, `--args`,
77
+ `--env` (`KEY=VALUE`), `--enabled/--no-enabled`, and `--auth oauth` prompts.
78
+
79
+ ### Testing
80
+
81
+ `mcp-plugin test` verifies the plugin itself end-to-end: it spawns the real
82
+ plugin server (`python -m mcp_plugin.server` — the same entry Slife launches),
83
+ reads its `{"port": N}` ready signal, connects over Streamable HTTP, checks the
84
+ management tools are served, and reports the external servers the plugin
85
+ auto-connected. `--port N` pins the server's port instead of auto-assigning.
86
+
87
+ `mcp-plugin test mcp <server>` is the opposite check — it bare-connects to one
88
+ external MCP server using the raw `mcp` SDK (no plugin framework), confirms it
89
+ speaks MCP, and lists its tools.
90
+
91
+ ## Plugin contract
92
+
93
+ An MCP-plugin distribution exposes a module that hosts its own FastMCP server
94
+ (transport: streamable HTTP on an auto-assigned port, port signaled to stdout as
95
+ `{"port": N}`). Slife discovers it via `plugins.external` in `slife.json5` and
96
+ spawns `python -m <module>`. The management tools (`mcp_set`, `mcp_remove`,
97
+ `mcp_set_enabled`, `mcp_list`, `mcp_list_tools`, `__mcp_call_tool`,
98
+ `__mcp_connection_status`) are kept separate from the servers they manage.
@@ -0,0 +1,10 @@
1
+ """mcp_plugin — standalone MCP gateway.
2
+
3
+ Persistent connections to external MCP servers (stdio, SSE, streamable HTTP),
4
+ OAuth 2.0 device-code flow, and a management CLI. Ships with Slife as its MCP
5
+ plugin but has no dependency on it.
6
+ """
7
+
8
+ __version__ = "0.1.0"
9
+
10
+ __all__ = ["__version__"]
@@ -0,0 +1,8 @@
1
+ """Entry point for `python -m mcp_plugin` and the `mcp-plugin` console script."""
2
+
3
+ import sys
4
+
5
+ from mcp_plugin.cli import main
6
+
7
+ if __name__ == "__main__":
8
+ sys.exit(main())