coreforged-mcp 0.1.0__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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CoreForged LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,223 @@
1
+ Metadata-Version: 2.4
2
+ Name: coreforged-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP gateway that docks multiple servers behind one endpoint with named loadout profiles
5
+ Author-email: CoreForged LLC <corporate@coreforged.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://coreforged.com/products/coreforged-mcp
8
+ Project-URL: Repository, https://github.com/coreforged/coreforged-mcp
9
+ Project-URL: Documentation, https://github.com/coreforged/coreforged-mcp#readme
10
+ Keywords: mcp,claude,ai,gateway,plugins
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: mcp[cli]<2,>=1.0.0
24
+ Provides-Extra: keyring
25
+ Requires-Dist: coreforged-mcp; extra == "keyring"
26
+ Provides-Extra: all
27
+ Requires-Dist: coreforged-mcp; extra == "all"
28
+ Provides-Extra: test
29
+ Requires-Dist: pytest>=8.0; extra == "test"
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == "test"
31
+ Dynamic: license-file
32
+
33
+ # CoreforgedMCP
34
+
35
+ **One MCP server to dock them all.**
36
+
37
+ CoreforgedMCP is a gateway that consolidates multiple MCP servers behind a single endpoint. Instead of configuring 5 separate servers in your `.mcp.json`, you configure one — and control which plugins load with a single environment variable.
38
+
39
+ ```
40
+ Before: 5 servers × 5 processes × 5 config blocks
41
+ After: 1 server × 1 process × 1 config block
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ ```bash
47
+ pip install coreforged-mcp
48
+ coreforged-mcp init
49
+ ```
50
+
51
+ This adds CoreforgedMCP to your `.mcp.json`. Restart Claude Code — you're running.
52
+
53
+ ## What You Get
54
+
55
+ ### The Gateway (free, open source)
56
+
57
+ - **Plugin docking** — native Python plugins load in-process; proxy plugins spawn as subprocesses
58
+ - **Named loadouts** — switch your entire tool stack by setting `COREFORGED_LOADOUT=analytics`
59
+ - **Plugin discovery** — drop a plugin into `~/.coreforged/plugins/` and it auto-loads
60
+ - **Cross-platform** — Windows, Mac, Linux
61
+
62
+ ### KeyRing (bundled)
63
+
64
+ Your API keys never enter the conversation. The keyring retrieves the secret, makes the authenticated API call, and returns only the response data. Every checkout is logged.
65
+
66
+ ```
67
+ Agent: "Call the GitHub API with my token"
68
+ → KeyRing retrieves token from encrypted store
69
+ → KeyRing makes the API call
70
+ → KeyRing returns the response data
71
+ → Token never appears in tool results or context
72
+ ```
73
+
74
+ ## Usage
75
+
76
+ ### Basic (default plugins)
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "coreforged": {
82
+ "command": "coreforged-mcp",
83
+ "args": ["run"]
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### With a loadout
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "coreforged": {
95
+ "command": "coreforged-mcp",
96
+ "args": ["run"],
97
+ "env": {
98
+ "COREFORGED_LOADOUT": "analytics"
99
+ }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Specific plugins only
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "coreforged": {
111
+ "command": "coreforged-mcp",
112
+ "args": ["run"],
113
+ "env": {
114
+ "COREFORGED_PLUGINS": "keyring,my-custom-plugin"
115
+ }
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## Installing Plugins
122
+
123
+ ### From a zip file
124
+
125
+ ```bash
126
+ coreforged-mcp install-plugin analytics-bundle.zip --key YOUR_LICENSE_KEY
127
+ ```
128
+
129
+ Plugins install to `~/.coreforged/plugins/` and are discovered automatically on next restart.
130
+
131
+ ### From a directory
132
+
133
+ Drop any directory with a `plugin.json` manifest into `~/.coreforged/plugins/`:
134
+
135
+ ```
136
+ ~/.coreforged/plugins/
137
+ ├── my-plugin/
138
+ │ ├── plugin.json
139
+ │ └── server.py
140
+ ```
141
+
142
+ ## Writing a Plugin
143
+
144
+ A plugin is any Python module with a FastMCP instance. If it runs standalone, it docks into the gateway.
145
+
146
+ **1. Write the server**
147
+
148
+ ```python
149
+ # my-plugin/server.py
150
+ from mcp.server.fastmcp import FastMCP
151
+
152
+ mcp = FastMCP("my-plugin", instructions="What this does.")
153
+
154
+ @mcp.tool()
155
+ def my_tool(query: str) -> str:
156
+ """Tool description."""
157
+ return do_something(query)
158
+
159
+ if __name__ == "__main__":
160
+ mcp.run()
161
+ ```
162
+
163
+ **2. Add the manifest**
164
+
165
+ ```json
166
+ // my-plugin/plugin.json
167
+ {
168
+ "name": "my-plugin",
169
+ "version": "0.1.0",
170
+ "description": "What it does",
171
+ "type": "native",
172
+ "module": "server",
173
+ "mcp_attr": "mcp",
174
+ "default": false
175
+ }
176
+ ```
177
+
178
+ **3. Test**
179
+
180
+ ```bash
181
+ # Standalone
182
+ python my-plugin/server.py
183
+
184
+ # Docked
185
+ cp -r my-plugin ~/.coreforged/plugins/
186
+ coreforged-mcp status
187
+ ```
188
+
189
+ A template plugin is included at `src/coreforged_mcp/plugins/_template/`.
190
+
191
+ ## Plugin Types
192
+
193
+ | Type | How It Works | Best For |
194
+ |------|-------------|----------|
195
+ | **Native** | Python module imported in-process | Python tools, zero overhead |
196
+ | **Proxy** | External process spawned, tools bridged via JSON-RPC | Node.js, Go, Rust servers |
197
+
198
+ ## CLI Commands
199
+
200
+ | Command | What It Does |
201
+ |---------|-------------|
202
+ | `coreforged-mcp run` | Start the gateway server |
203
+ | `coreforged-mcp status` | Show discovered plugins and loadouts |
204
+ | `coreforged-mcp init` | Add CoreforgedMCP to `.mcp.json` |
205
+ | `coreforged-mcp install-plugin <path> [--key KEY]` | Install a plugin from a zip |
206
+
207
+ ## Available Plugins
208
+
209
+ | Plugin | Source | What It Does |
210
+ |--------|--------|-------------|
211
+ | **KeyRing** | Bundled | Sovereign secrets — API keys never enter context |
212
+ | Digital Analytics | [coreforged.com](https://coreforged.com) | GA4 + Search Console + PageSpeed |
213
+ | SEO Bundle | [coreforged.com](https://coreforged.com) | Keyword research + SERP analysis |
214
+
215
+ ## License
216
+
217
+ MIT — the gateway is free and open source. Some plugins on [coreforged.com](https://coreforged.com) are commercially licensed.
218
+
219
+ ## Contributing
220
+
221
+ PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
222
+
223
+ Built by [CoreForged LLC](https://coreforged.com).
@@ -0,0 +1,191 @@
1
+ # CoreforgedMCP
2
+
3
+ **One MCP server to dock them all.**
4
+
5
+ CoreforgedMCP is a gateway that consolidates multiple MCP servers behind a single endpoint. Instead of configuring 5 separate servers in your `.mcp.json`, you configure one — and control which plugins load with a single environment variable.
6
+
7
+ ```
8
+ Before: 5 servers × 5 processes × 5 config blocks
9
+ After: 1 server × 1 process × 1 config block
10
+ ```
11
+
12
+ ## Quick Start
13
+
14
+ ```bash
15
+ pip install coreforged-mcp
16
+ coreforged-mcp init
17
+ ```
18
+
19
+ This adds CoreforgedMCP to your `.mcp.json`. Restart Claude Code — you're running.
20
+
21
+ ## What You Get
22
+
23
+ ### The Gateway (free, open source)
24
+
25
+ - **Plugin docking** — native Python plugins load in-process; proxy plugins spawn as subprocesses
26
+ - **Named loadouts** — switch your entire tool stack by setting `COREFORGED_LOADOUT=analytics`
27
+ - **Plugin discovery** — drop a plugin into `~/.coreforged/plugins/` and it auto-loads
28
+ - **Cross-platform** — Windows, Mac, Linux
29
+
30
+ ### KeyRing (bundled)
31
+
32
+ Your API keys never enter the conversation. The keyring retrieves the secret, makes the authenticated API call, and returns only the response data. Every checkout is logged.
33
+
34
+ ```
35
+ Agent: "Call the GitHub API with my token"
36
+ → KeyRing retrieves token from encrypted store
37
+ → KeyRing makes the API call
38
+ → KeyRing returns the response data
39
+ → Token never appears in tool results or context
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ### Basic (default plugins)
45
+
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "coreforged": {
50
+ "command": "coreforged-mcp",
51
+ "args": ["run"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### With a loadout
58
+
59
+ ```json
60
+ {
61
+ "mcpServers": {
62
+ "coreforged": {
63
+ "command": "coreforged-mcp",
64
+ "args": ["run"],
65
+ "env": {
66
+ "COREFORGED_LOADOUT": "analytics"
67
+ }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Specific plugins only
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "coreforged": {
79
+ "command": "coreforged-mcp",
80
+ "args": ["run"],
81
+ "env": {
82
+ "COREFORGED_PLUGINS": "keyring,my-custom-plugin"
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Installing Plugins
90
+
91
+ ### From a zip file
92
+
93
+ ```bash
94
+ coreforged-mcp install-plugin analytics-bundle.zip --key YOUR_LICENSE_KEY
95
+ ```
96
+
97
+ Plugins install to `~/.coreforged/plugins/` and are discovered automatically on next restart.
98
+
99
+ ### From a directory
100
+
101
+ Drop any directory with a `plugin.json` manifest into `~/.coreforged/plugins/`:
102
+
103
+ ```
104
+ ~/.coreforged/plugins/
105
+ ├── my-plugin/
106
+ │ ├── plugin.json
107
+ │ └── server.py
108
+ ```
109
+
110
+ ## Writing a Plugin
111
+
112
+ A plugin is any Python module with a FastMCP instance. If it runs standalone, it docks into the gateway.
113
+
114
+ **1. Write the server**
115
+
116
+ ```python
117
+ # my-plugin/server.py
118
+ from mcp.server.fastmcp import FastMCP
119
+
120
+ mcp = FastMCP("my-plugin", instructions="What this does.")
121
+
122
+ @mcp.tool()
123
+ def my_tool(query: str) -> str:
124
+ """Tool description."""
125
+ return do_something(query)
126
+
127
+ if __name__ == "__main__":
128
+ mcp.run()
129
+ ```
130
+
131
+ **2. Add the manifest**
132
+
133
+ ```json
134
+ // my-plugin/plugin.json
135
+ {
136
+ "name": "my-plugin",
137
+ "version": "0.1.0",
138
+ "description": "What it does",
139
+ "type": "native",
140
+ "module": "server",
141
+ "mcp_attr": "mcp",
142
+ "default": false
143
+ }
144
+ ```
145
+
146
+ **3. Test**
147
+
148
+ ```bash
149
+ # Standalone
150
+ python my-plugin/server.py
151
+
152
+ # Docked
153
+ cp -r my-plugin ~/.coreforged/plugins/
154
+ coreforged-mcp status
155
+ ```
156
+
157
+ A template plugin is included at `src/coreforged_mcp/plugins/_template/`.
158
+
159
+ ## Plugin Types
160
+
161
+ | Type | How It Works | Best For |
162
+ |------|-------------|----------|
163
+ | **Native** | Python module imported in-process | Python tools, zero overhead |
164
+ | **Proxy** | External process spawned, tools bridged via JSON-RPC | Node.js, Go, Rust servers |
165
+
166
+ ## CLI Commands
167
+
168
+ | Command | What It Does |
169
+ |---------|-------------|
170
+ | `coreforged-mcp run` | Start the gateway server |
171
+ | `coreforged-mcp status` | Show discovered plugins and loadouts |
172
+ | `coreforged-mcp init` | Add CoreforgedMCP to `.mcp.json` |
173
+ | `coreforged-mcp install-plugin <path> [--key KEY]` | Install a plugin from a zip |
174
+
175
+ ## Available Plugins
176
+
177
+ | Plugin | Source | What It Does |
178
+ |--------|--------|-------------|
179
+ | **KeyRing** | Bundled | Sovereign secrets — API keys never enter context |
180
+ | Digital Analytics | [coreforged.com](https://coreforged.com) | GA4 + Search Console + PageSpeed |
181
+ | SEO Bundle | [coreforged.com](https://coreforged.com) | Keyword research + SERP analysis |
182
+
183
+ ## License
184
+
185
+ MIT — the gateway is free and open source. Some plugins on [coreforged.com](https://coreforged.com) are commercially licensed.
186
+
187
+ ## Contributing
188
+
189
+ PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
190
+
191
+ Built by [CoreForged LLC](https://coreforged.com).
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "coreforged-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP gateway that docks multiple servers behind one endpoint with named loadout profiles"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ authors = [{name = "CoreForged LLC", email = "corporate@coreforged.com"}]
13
+ keywords = ["mcp", "claude", "ai", "gateway", "plugins"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Software Development :: Libraries",
24
+ ]
25
+
26
+ dependencies = [
27
+ "mcp[cli]>=1.0.0,<2",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ keyring = ["coreforged-mcp"]
32
+ all = ["coreforged-mcp"]
33
+ test = ["pytest>=8.0", "pytest-asyncio>=0.23"]
34
+
35
+ [project.urls]
36
+ Homepage = "https://coreforged.com/products/coreforged-mcp"
37
+ Repository = "https://github.com/coreforged/coreforged-mcp"
38
+ Documentation = "https://github.com/coreforged/coreforged-mcp#readme"
39
+
40
+ [project.scripts]
41
+ coreforged-mcp = "coreforged_mcp.cli:main"
42
+
43
+ [tool.setuptools.packages.find]
44
+ where = ["src"]
45
+ include = ["coreforged_mcp*"]
46
+
47
+ [tool.setuptools.package-data]
48
+ "coreforged_mcp" = ["plugins/*/plugin.json", "plugins/*/permissions.json", "plugins/*/secret_manifest.json", "loadouts.json"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """CoreforgedMCP — one MCP server to dock them all."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,148 @@
1
+ """CoreforgedMCP CLI — manage the gateway and plugins."""
2
+
3
+ import argparse
4
+ import json
5
+ import os
6
+ import sys
7
+
8
+
9
+ def cmd_run(args):
10
+ """Start the gateway server."""
11
+ from coreforged_mcp.gateway import gateway
12
+ gateway.run()
13
+
14
+
15
+ def cmd_status(args):
16
+ """Show gateway status without starting the server."""
17
+ from coreforged_mcp.gateway import _discover_plugins, _plugin_status, _loadouts, _load_loadouts
18
+ _load_loadouts()
19
+ registry = _discover_plugins()
20
+ print(f"CoreforgedMCP v{_get_version()}")
21
+ print(f"Discovered plugins: {len(registry)}")
22
+ for name, manifest in registry.items():
23
+ source = manifest.get("_source", "?")
24
+ default = "default" if manifest.get("default") else "opt-in"
25
+ print(f" {name} ({source}, {default}): {manifest.get('description', '')}")
26
+ if _loadouts:
27
+ print(f"\nLoadouts: {len(_loadouts)}")
28
+ for name, profile in _loadouts.items():
29
+ print(f" {name}: {profile.get('description', '')}")
30
+
31
+
32
+ def cmd_init(args):
33
+ """Initialize CoreforgedMCP config for this project."""
34
+ mcp_json_path = os.path.join(os.getcwd(), ".mcp.json")
35
+
36
+ if os.path.exists(mcp_json_path):
37
+ with open(mcp_json_path, encoding="utf-8") as f:
38
+ config = json.load(f)
39
+ else:
40
+ config = {}
41
+
42
+ servers = config.setdefault("mcpServers", {})
43
+ if "coreforged" in servers:
44
+ print("CoreforgedMCP already configured in .mcp.json")
45
+ return
46
+
47
+ servers["coreforged"] = {
48
+ "command": "coreforged-mcp",
49
+ "args": ["run"],
50
+ }
51
+
52
+ with open(mcp_json_path, "w", encoding="utf-8") as f:
53
+ json.dump(config, f, indent=2)
54
+
55
+ print(f"Added CoreforgedMCP to {mcp_json_path}")
56
+ print("Restart Claude Code to load the gateway.")
57
+
58
+
59
+ def cmd_install_plugin(args):
60
+ """Install a plugin from a zip file."""
61
+ import zipfile
62
+ import shutil
63
+
64
+ zip_path = args.path
65
+ if not os.path.isfile(zip_path):
66
+ print(f"Error: {zip_path} not found", file=sys.stderr)
67
+ sys.exit(1)
68
+
69
+ user_dir = os.path.join(os.path.expanduser("~"), ".coreforged", "plugins")
70
+ os.makedirs(user_dir, exist_ok=True)
71
+
72
+ with zipfile.ZipFile(zip_path, "r") as zf:
73
+ names = zf.namelist()
74
+ manifest_candidates = [n for n in names if n.endswith("plugin.json")]
75
+ if not manifest_candidates:
76
+ print("Error: no plugin.json found in archive", file=sys.stderr)
77
+ sys.exit(1)
78
+
79
+ manifest_path = manifest_candidates[0]
80
+ manifest_data = json.loads(zf.read(manifest_path))
81
+ plugin_name = manifest_data.get("name", os.path.basename(zip_path).replace(".zip", ""))
82
+
83
+ if args.key:
84
+ manifest_data["license_key"] = args.key
85
+
86
+ dest = os.path.join(user_dir, plugin_name)
87
+ if os.path.exists(dest):
88
+ shutil.rmtree(dest)
89
+
90
+ prefix = os.path.dirname(manifest_path)
91
+ for member in names:
92
+ if prefix and not member.startswith(prefix):
93
+ continue
94
+ rel = member[len(prefix):].lstrip("/") if prefix else member
95
+ if not rel or rel.endswith("/"):
96
+ continue
97
+ target = os.path.join(dest, rel)
98
+ os.makedirs(os.path.dirname(target), exist_ok=True)
99
+ with open(target, "wb") as out:
100
+ out.write(zf.read(member))
101
+
102
+ if args.key:
103
+ manifest_out = os.path.join(dest, "plugin.json")
104
+ with open(manifest_out, "w", encoding="utf-8") as f:
105
+ json.dump(manifest_data, f, indent=2)
106
+
107
+ print(f"Installed plugin '{plugin_name}' to {dest}")
108
+ print("Restart Claude Code to load the new plugin.")
109
+
110
+
111
+ def _get_version():
112
+ from coreforged_mcp import __version__
113
+ return __version__
114
+
115
+
116
+ def main():
117
+ parser = argparse.ArgumentParser(
118
+ prog="coreforged-mcp",
119
+ description="CoreforgedMCP — one MCP server to dock them all",
120
+ )
121
+ parser.add_argument("--version", action="version", version=f"%(prog)s {_get_version()}")
122
+ sub = parser.add_subparsers(dest="command")
123
+
124
+ sub.add_parser("run", help="Start the gateway server")
125
+ sub.add_parser("status", help="Show discovered plugins and loadouts")
126
+ sub.add_parser("init", help="Add CoreforgedMCP to .mcp.json in the current directory")
127
+
128
+ install = sub.add_parser("install-plugin", help="Install a plugin from a zip file")
129
+ install.add_argument("path", help="Path to plugin .zip file")
130
+ install.add_argument("--key", help="License key for paid plugins")
131
+
132
+ args = parser.parse_args()
133
+
134
+ commands = {
135
+ "run": cmd_run,
136
+ "status": cmd_status,
137
+ "init": cmd_init,
138
+ "install-plugin": cmd_install_plugin,
139
+ }
140
+
141
+ if args.command in commands:
142
+ commands[args.command](args)
143
+ else:
144
+ parser.print_help()
145
+
146
+
147
+ if __name__ == "__main__":
148
+ main()