open-edison 0.1.44__tar.gz → 0.1.72rc1__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.
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/PKG-INFO +2 -21
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/README.md +1 -20
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/README.md +2 -3
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/architecture/single_user_design.md +2 -10
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/core/configuration.md +32 -2
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/core/project_structure.md +29 -29
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/core/proxy_usage.md +64 -114
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/deployment/docker.md +4 -1
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/deployment/local.md +7 -8
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/development/contributing.md +1 -1
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/development/development_guide.md +34 -49
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/development/testing.md +30 -47
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/quick-reference/api_reference.md +42 -103
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/docs/quick-reference/config_quick_start.md +4 -4
- open_edison-0.1.72rc1/docs/testing_status.md +35 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/pyproject.toml +1 -1
- open_edison-0.1.72rc1/src/cli.py +151 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/config.py +30 -9
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/events.py +5 -2
- open_edison-0.1.72rc1/src/frontend_dist/assets/index-D05VN_1l.css +1 -0
- open_edison-0.1.72rc1/src/frontend_dist/assets/index-D6ziuTsl.js +51 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/frontend_dist/index.html +2 -2
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/frontend_dist/sw.js +22 -2
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/__main__.py +0 -2
- open_edison-0.1.72rc1/src/mcp_importer/api.py +414 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/export_cli.py +2 -2
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/exporters.py +1 -1
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/import_api.py +0 -2
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/parsers.py +47 -9
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/quick_cli.py +0 -2
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/types.py +0 -2
- open_edison-0.1.72rc1/src/mcp_stdio_capture.py +144 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/middleware/data_access_tracker.py +49 -4
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/middleware/session_tracking.py +123 -34
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/oauth_manager.py +5 -3
- open_edison-0.1.72rc1/src/oauth_override.py +10 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/permissions.py +110 -10
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/server.py +57 -16
- open_edison-0.1.72rc1/src/setup_tui/main.py +296 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/single_user_mcp.py +246 -105
- open_edison-0.1.72rc1/src/tools/io.py +35 -0
- open_edison-0.1.72rc1/src/vulture_whitelist.py +3 -0
- open_edison-0.1.44/src/cli.py +0 -234
- open_edison-0.1.44/src/frontend_dist/assets/index-BUUcUfTt.js +0 -51
- open_edison-0.1.44/src/frontend_dist/assets/index-o6_8mdM8.css +0 -1
- open_edison-0.1.44/src/mcp_importer/api.py +0 -204
- open_edison-0.1.44/src/setup_tui/main.py +0 -157
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/.gitignore +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/LICENSE +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/config.json +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/desktop_ext/README.md +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/hatch_build.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/installation_test/README.md +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/prompt_permissions.json +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/resource_permissions.json +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/__init__.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/__main__.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/config.pyi +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/__init__.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/cli.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/importers.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/merge.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/mcp_importer/paths.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/setup_tui/__init__.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/src/telemetry.py +0 -0
- {open_edison-0.1.44 → open_edison-0.1.72rc1}/tool_permissions.json +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: open-edison
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.72rc1
|
4
4
|
Summary: Open-source MCP security, aggregation, and monitoring. Single-user, self-hosted MCP proxy.
|
5
5
|
Author-email: Hugo Berg <hugo@edison.watch>
|
6
6
|
License-File: LICENSE
|
@@ -72,13 +72,7 @@ curl -fsSL https://raw.githubusercontent.com/Edison-Watch/open-edison/main/curl_
|
|
72
72
|
```
|
73
73
|
|
74
74
|
Run locally with uvx: `uvx open-edison`
|
75
|
-
|
76
|
-
Optionally, run the setup wizard to import/configure MCP:
|
77
|
-
|
78
|
-
```bash
|
79
|
-
uv run python -m src.setup_tui.main
|
80
|
-
# add --dry-run to preview without writing
|
81
|
-
```
|
75
|
+
That will run the setup wizard if necessary.
|
82
76
|
|
83
77
|
<details>
|
84
78
|
<summary>⬇️ Install Node.js/npm (optional for MCP tools)</summary>
|
@@ -129,19 +123,6 @@ OPEN_EDISON_CONFIG_DIR=~/edison-config open-edison run
|
|
129
123
|
|
130
124
|
</details>
|
131
125
|
|
132
|
-
<details>
|
133
|
-
<summary>🔄 Import from Cursor/VS Code/Claude Code</summary>
|
134
|
-
|
135
|
-
Run the interactive setup wizard to detect clients, import servers, and configure your editor:
|
136
|
-
|
137
|
-
```bash
|
138
|
-
uv run python -m src.setup_tui.main
|
139
|
-
```
|
140
|
-
|
141
|
-
Use `--dry-run` to preview without writing.
|
142
|
-
|
143
|
-
</details>
|
144
|
-
|
145
126
|
<details>
|
146
127
|
<summary><img src="https://img.shields.io/badge/Docker-2CA5E0?style=for-the-badge&logo=docker&logoColor=white" alt="Docker"> Run with Docker</summary>
|
147
128
|
|
@@ -47,13 +47,7 @@ curl -fsSL https://raw.githubusercontent.com/Edison-Watch/open-edison/main/curl_
|
|
47
47
|
```
|
48
48
|
|
49
49
|
Run locally with uvx: `uvx open-edison`
|
50
|
-
|
51
|
-
Optionally, run the setup wizard to import/configure MCP:
|
52
|
-
|
53
|
-
```bash
|
54
|
-
uv run python -m src.setup_tui.main
|
55
|
-
# add --dry-run to preview without writing
|
56
|
-
```
|
50
|
+
That will run the setup wizard if necessary.
|
57
51
|
|
58
52
|
<details>
|
59
53
|
<summary>⬇️ Install Node.js/npm (optional for MCP tools)</summary>
|
@@ -104,19 +98,6 @@ OPEN_EDISON_CONFIG_DIR=~/edison-config open-edison run
|
|
104
98
|
|
105
99
|
</details>
|
106
100
|
|
107
|
-
<details>
|
108
|
-
<summary>🔄 Import from Cursor/VS Code/Claude Code</summary>
|
109
|
-
|
110
|
-
Run the interactive setup wizard to detect clients, import servers, and configure your editor:
|
111
|
-
|
112
|
-
```bash
|
113
|
-
uv run python -m src.setup_tui.main
|
114
|
-
```
|
115
|
-
|
116
|
-
Use `--dry-run` to preview without writing.
|
117
|
-
|
118
|
-
</details>
|
119
|
-
|
120
101
|
<details>
|
121
102
|
<summary><img src="https://img.shields.io/badge/Docker-2CA5E0?style=for-the-badge&logo=docker&logoColor=white" alt="Docker"> Run with Docker</summary>
|
122
103
|
|
@@ -24,7 +24,7 @@ Fast lookup guides:
|
|
24
24
|
Design decisions and technical deep-dives:
|
25
25
|
|
26
26
|
- **[Single-User Design](architecture/single_user_design.md)** - Why simplicity over multi-user complexity
|
27
|
-
-
|
27
|
+
- JSON vs Database config decisions: integrated into the configuration guide
|
28
28
|
|
29
29
|
### 💻 **Development** [`development/`](development/)
|
30
30
|
|
@@ -40,8 +40,7 @@ Production deployment guides:
|
|
40
40
|
|
41
41
|
- **[Docker Deployment](deployment/docker.md)** - Container-based deployment
|
42
42
|
- **[Local Installation](deployment/local.md)** - Local development setup
|
43
|
-
|
44
|
-
|
43
|
+
|
45
44
|
## 🚀 **Getting Started**
|
46
45
|
|
47
46
|
New to Open Edison? Start here:
|
@@ -38,17 +38,9 @@ Open Edison deliberately embraces a **single-user design philosophy** that prior
|
|
38
38
|
|
39
39
|
See [configuration.md](../core/configuration.md)
|
40
40
|
|
41
|
-
## MCP Server Design
|
41
|
+
## MCP Server and API Design
|
42
42
|
|
43
|
-
See [
|
44
|
-
|
45
|
-
## Authentication Design
|
46
|
-
|
47
|
-
See [authentication.md](../core/authentication.md)
|
48
|
-
|
49
|
-
## API Design
|
50
|
-
|
51
|
-
See [api.md](../core/api.md)
|
43
|
+
See [Project Structure](../core/project_structure.md) and [API Reference](../quick-reference/api_reference.md)
|
52
44
|
|
53
45
|
## Comparison with edison.watch
|
54
46
|
|
@@ -122,7 +122,7 @@ If `config.json` doesn't exist, Open Edison creates a default configuration:
|
|
122
122
|
```bash
|
123
123
|
make setup
|
124
124
|
# or
|
125
|
-
python -c "from src.config import Config; Config.create_default().save()"
|
125
|
+
python -c "from src.config import Config; cfg=Config(); cfg.create_default(); cfg.save()"
|
126
126
|
```
|
127
127
|
|
128
128
|
### Validation
|
@@ -133,7 +133,7 @@ Configuration is validated on startup using Python dataclasses:
|
|
133
133
|
from src.config import Config
|
134
134
|
|
135
135
|
# Load and validate configuration
|
136
|
-
config = Config
|
136
|
+
config = Config()
|
137
137
|
print(f"Server will run on {config.server.host}:{config.server.port}")
|
138
138
|
```
|
139
139
|
|
@@ -151,6 +151,36 @@ make run
|
|
151
151
|
|
152
152
|
Later on this will be doable via the API
|
153
153
|
|
154
|
+
### Configuration Directory
|
155
|
+
|
156
|
+
By default, configuration is loaded from a platform-appropriate config directory. You can override the location using `OPEN_EDISON_CONFIG_DIR`.
|
157
|
+
|
158
|
+
Resolution order:
|
159
|
+
|
160
|
+
1. `OPEN_EDISON_CONFIG_DIR` environment variable, if set
|
161
|
+
2. OS-specific defaults (e.g., `~/Library/Application Support/Open Edison` on macOS, `$XDG_CONFIG_HOME/open-edison` on Linux)
|
162
|
+
3. Fallback to `~/.open-edison`
|
163
|
+
|
164
|
+
### Telemetry
|
165
|
+
|
166
|
+
Open Edison can emit basic telemetry metrics.
|
167
|
+
|
168
|
+
```json
|
169
|
+
{
|
170
|
+
"telemetry": {
|
171
|
+
"enabled": true,
|
172
|
+
"otlp_endpoint": "https://otel-collector-production-e7a6.up.railway.app/v1/metrics",
|
173
|
+
"headers": { "x-auth": "token" },
|
174
|
+
"export_interval_ms": 60000
|
175
|
+
}
|
176
|
+
}
|
177
|
+
```
|
178
|
+
|
179
|
+
- `enabled`: Toggle telemetry on/off
|
180
|
+
- `otlp_endpoint`: Custom OTLP endpoint (defaults to a hosted collector if not set)
|
181
|
+
- `headers`: Optional headers for the exporter
|
182
|
+
- `export_interval_ms`: Export interval in milliseconds
|
183
|
+
|
154
184
|
## Security Considerations
|
155
185
|
|
156
186
|
### API Key Security
|
@@ -10,12 +10,12 @@ Open Edison is a **single-user MCP (Model Context Protocol) proxy server** desig
|
|
10
10
|
|
11
11
|
```
|
12
12
|
open-edison/
|
13
|
-
├── main.py # Entry point - starts
|
13
|
+
├── main.py # Entry point - starts both MCP and API servers
|
14
14
|
├── config.json # JSON configuration (no database needed)
|
15
15
|
├── src/ # Main source code
|
16
|
-
│ ├── server.py # FastAPI
|
16
|
+
│ ├── server.py # FastAPI management API + dashboard wiring
|
17
17
|
│ ├── config.py # JSON configuration management
|
18
|
-
│ ├──
|
18
|
+
│ ├── single_user_mcp.py # FastMCP single-user manager (MCP protocol server)
|
19
19
|
│ └── __init__.py # Package initialization
|
20
20
|
├── tests/ # Test suite
|
21
21
|
│ ├── test_config.py # Configuration tests
|
@@ -31,11 +31,11 @@ open-edison/
|
|
31
31
|
|
32
32
|
#### 1. Main Server (`src/server.py`)
|
33
33
|
|
34
|
-
- **OpenEdisonProxy**:
|
35
|
-
- **
|
36
|
-
- **
|
37
|
-
- **MCP
|
38
|
-
- **
|
34
|
+
- **OpenEdisonProxy**: Orchestrates both servers and routes
|
35
|
+
- **Ports**: FastMCP protocol on 3000 (path `/mcp/`), FastAPI management API on 3001
|
36
|
+
- **Authentication**: Bearer token API key for management endpoints
|
37
|
+
- **MCP management**: Mount/unmount/reinitialize configured MCP servers
|
38
|
+
- **Dashboard**: Serves packaged frontend at `/dashboard` on the API server
|
39
39
|
|
40
40
|
#### 2. Configuration System (`src/config.py`)
|
41
41
|
|
@@ -44,12 +44,11 @@ open-edison/
|
|
44
44
|
- **Auto-generation**: Creates default config if missing
|
45
45
|
- **Hot reload**: Configuration changes require restart (keeps it simple)
|
46
46
|
|
47
|
-
#### 3. MCP
|
47
|
+
#### 3. Single-User MCP (`src/single_user_mcp.py`)
|
48
48
|
|
49
|
-
- **
|
50
|
-
- **
|
51
|
-
- **
|
52
|
-
- **Subprocess isolation**: Each MCP server runs independently
|
49
|
+
- **FastMCP integration**: Hosts the MCP protocol server
|
50
|
+
- **Server lifecycle**: Initializes and manages configured servers
|
51
|
+
- **Mounting**: Supports dynamic mount/unmount via API
|
53
52
|
|
54
53
|
## Data Flow
|
55
54
|
|
@@ -90,7 +89,7 @@ MCP over streamable HTTP works by sending JSON-RPC messages from the client to t
|
|
90
89
|
|
91
90
|
## Development Stack
|
92
91
|
|
93
|
-
- **Python 3.12+** with **
|
92
|
+
- **Python 3.12+** with **uv** package management
|
94
93
|
- **FastAPI** for HTTP API endpoints
|
95
94
|
- **JSON** for configuration (no database)
|
96
95
|
- **Subprocess** for MCP server management
|
@@ -140,27 +139,28 @@ The project uses a **simple JSON configuration approach** with no database depen
|
|
140
139
|
- **Portable**: Easy to backup and restore
|
141
140
|
- **Human Readable**: Easy to edit and understand
|
142
141
|
|
143
|
-
## API Endpoints (Port
|
142
|
+
## API Endpoints (Management API on Port 3001)
|
144
143
|
|
145
|
-
###
|
144
|
+
### Public
|
146
145
|
|
147
|
-
- **GET /health**: Health check
|
148
|
-
- **GET /mcp/status**:
|
146
|
+
- **GET /health**: Health check (no auth)
|
147
|
+
- **GET /mcp/status**: List configured MCP servers and enabled flags (no auth)
|
148
|
+
- **GET /sessions**: Recent session summaries (no auth)
|
149
149
|
|
150
|
-
###
|
150
|
+
### Auth required (Bearer: `Authorization: Bearer <api_key>`)
|
151
151
|
|
152
|
-
- **
|
153
|
-
- **POST /mcp/
|
152
|
+
- **GET /mcp/mounted**: List currently mounted servers
|
153
|
+
- **POST /mcp/reinitialize**: Reinitialize servers from config
|
154
|
+
- **POST /mcp/mount/{server_name}**: Mount a server by name
|
155
|
+
- **DELETE /mcp/mount/{server_name}**: Unmount a server by name
|
156
|
+
- **GET /mcp/oauth/status** and related `/mcp/oauth/*` endpoints: OAuth status/management for remote servers
|
154
157
|
|
155
|
-
###
|
158
|
+
### Utilities
|
156
159
|
|
157
|
-
- **POST /
|
160
|
+
- **POST /api/permissions-changed**: Invalidate internal caches after JSON permission updates
|
161
|
+
- **GET /events**: Server-Sent Events stream
|
158
162
|
|
159
|
-
|
160
|
-
|
161
|
-
- **GET /sessions**: Get session logs (placeholder for future SQLite logging)
|
162
|
-
|
163
|
-
All endpoints except `/health` require API key authentication via `Authorization: Bearer <api_key>` header.
|
163
|
+
MCP protocol server runs on Port 3000 at path `/mcp/`.
|
164
164
|
|
165
165
|
## Getting Started
|
166
166
|
|
@@ -169,7 +169,7 @@ All endpoints except `/health` require API key authentication via `Authorization
|
|
169
169
|
3. **Configure MCP servers**: Edit `config.json` with your MCP servers
|
170
170
|
4. **Run server**: `make run`
|
171
171
|
|
172
|
-
The server
|
172
|
+
The MCP protocol server starts on `localhost:3000/mcp/`, and the management API + dashboard on `http://localhost:3001`.
|
173
173
|
|
174
174
|
## Design Philosophy
|
175
175
|
|
@@ -16,13 +16,7 @@ make run
|
|
16
16
|
uv run python main.py
|
17
17
|
```
|
18
18
|
|
19
|
-
The server
|
20
|
-
|
21
|
-
- **MCP Proxy**: Will proxy MCP calls (future implementation)
|
22
|
-
|
23
|
-
And api on `localhost:3001`
|
24
|
-
|
25
|
-
- **FastAPI**: REST endpoints for management
|
19
|
+
The MCP protocol server runs at `http://localhost:3000/mcp/` and the management API + dashboard are at `http://localhost:3001`.
|
26
20
|
|
27
21
|
### 2. Verify Server Health
|
28
22
|
|
@@ -40,7 +34,7 @@ curl http://localhost:3001/health
|
|
40
34
|
|
41
35
|
## HTTP API Reference
|
42
36
|
|
43
|
-
|
37
|
+
Most API endpoints require authentication; public endpoints are noted.
|
44
38
|
|
45
39
|
```bash
|
46
40
|
# Authentication header
|
@@ -69,11 +63,10 @@ curl http://localhost:3001/health
|
|
69
63
|
|
70
64
|
#### GET `/mcp/status`
|
71
65
|
|
72
|
-
Get
|
66
|
+
Get configured MCP servers and their enabled flags (public):
|
73
67
|
|
74
68
|
```bash
|
75
|
-
curl
|
76
|
-
http://localhost:3001/mcp/status
|
69
|
+
curl http://localhost:3001/mcp/status
|
77
70
|
```
|
78
71
|
|
79
72
|
**Response:**
|
@@ -81,103 +74,62 @@ curl -H "Authorization: Bearer your-api-key" \
|
|
81
74
|
```json
|
82
75
|
{
|
83
76
|
"servers": [
|
84
|
-
{
|
85
|
-
|
86
|
-
"enabled": true,
|
87
|
-
"running": true
|
88
|
-
},
|
89
|
-
{
|
90
|
-
"name": "github",
|
91
|
-
"enabled": false,
|
92
|
-
"running": false
|
93
|
-
}
|
77
|
+
{ "name": "filesystem", "enabled": true },
|
78
|
+
{ "name": "github", "enabled": false }
|
94
79
|
]
|
95
80
|
}
|
96
81
|
```
|
97
82
|
|
98
83
|
### MCP Server Control
|
99
84
|
|
100
|
-
####
|
85
|
+
#### GET `/mcp/mounted`
|
101
86
|
|
102
|
-
|
87
|
+
List currently mounted servers (auth):
|
103
88
|
|
104
89
|
```bash
|
105
|
-
curl -
|
106
|
-
|
107
|
-
http://localhost:3001/mcp/filesystem/start
|
108
|
-
```
|
109
|
-
|
110
|
-
**Response:**
|
111
|
-
|
112
|
-
```json
|
113
|
-
{
|
114
|
-
"message": "Server filesystem started successfully"
|
115
|
-
}
|
90
|
+
curl -H "Authorization: Bearer your-api-key" \
|
91
|
+
http://localhost:3001/mcp/mounted
|
116
92
|
```
|
117
93
|
|
118
|
-
#### POST `/mcp/
|
94
|
+
#### POST `/mcp/reinitialize`
|
119
95
|
|
120
|
-
|
96
|
+
Reinitialize servers from the current configuration (auth):
|
121
97
|
|
122
98
|
```bash
|
123
|
-
curl -X POST \
|
124
|
-
|
125
|
-
http://localhost:3001/mcp/filesystem/stop
|
99
|
+
curl -X POST -H "Authorization: Bearer your-api-key" \
|
100
|
+
http://localhost:3001/mcp/reinitialize
|
126
101
|
```
|
127
102
|
|
128
|
-
|
103
|
+
#### POST `/mcp/mount/{server_name}`
|
129
104
|
|
130
|
-
|
131
|
-
{
|
132
|
-
"message": "Server filesystem stopped successfully"
|
133
|
-
}
|
134
|
-
```
|
105
|
+
Mount a server by name (auth):
|
135
106
|
|
136
|
-
|
107
|
+
```bash
|
108
|
+
curl -X POST -H "Authorization: Bearer your-api-key" \
|
109
|
+
http://localhost:3001/mcp/mount/filesystem
|
110
|
+
```
|
137
111
|
|
138
|
-
####
|
112
|
+
#### DELETE `/mcp/mount/{server_name}`
|
139
113
|
|
140
|
-
|
114
|
+
Unmount a server by name (auth):
|
141
115
|
|
142
116
|
```bash
|
143
|
-
curl -X
|
144
|
-
|
145
|
-
-H "Content-Type: application/json" \
|
146
|
-
-d '{"method": "tools/list", "id": 1}' \
|
147
|
-
http://localhost:3001/mcp/call
|
117
|
+
curl -X DELETE -H "Authorization: Bearer your-api-key" \
|
118
|
+
http://localhost:3001/mcp/mount/filesystem
|
148
119
|
```
|
149
120
|
|
150
|
-
|
121
|
+
### MCP Communication
|
151
122
|
|
152
|
-
|
153
|
-
{
|
154
|
-
"jsonrpc": "2.0",
|
155
|
-
"id": 1,
|
156
|
-
"result": {
|
157
|
-
"message": "MCP request handling not yet implemented",
|
158
|
-
"request": {"method": "tools/list", "id": 1}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
```
|
123
|
+
Use an MCP client to connect to the MCP server at `http://localhost:3000/mcp/` (for example `npx -y mcp-remote http://localhost:3000/mcp/ --http-only`). The management API does not proxy JSON-RPC calls.
|
162
124
|
|
163
125
|
### Session Logging
|
164
126
|
|
165
127
|
#### GET `/sessions`
|
166
128
|
|
167
|
-
Get session
|
129
|
+
Get recent MCP session summaries (public):
|
168
130
|
|
169
131
|
```bash
|
170
|
-
curl
|
171
|
-
http://localhost:3001/sessions
|
172
|
-
```
|
173
|
-
|
174
|
-
**Response:**
|
175
|
-
|
176
|
-
```json
|
177
|
-
{
|
178
|
-
"sessions": [],
|
179
|
-
"message": "Session logging not yet implemented"
|
180
|
-
}
|
132
|
+
curl http://localhost:3001/sessions
|
181
133
|
```
|
182
134
|
|
183
135
|
## MCP Server Management
|
@@ -185,10 +137,9 @@ curl -H "Authorization: Bearer your-api-key" \
|
|
185
137
|
### Server Lifecycle
|
186
138
|
|
187
139
|
1. **Configuration**: Define servers in `config.json`
|
188
|
-
2. **
|
189
|
-
3. **Manual Control**:
|
190
|
-
4. **
|
191
|
-
5. **Process Management**: Servers run as subprocesses
|
140
|
+
2. **Initialization**: FastMCP initializes servers on startup
|
141
|
+
3. **Manual Control**: Mount/unmount servers via API
|
142
|
+
4. **Monitoring**: Check mounted servers and status endpoints
|
192
143
|
|
193
144
|
### Process Management
|
194
145
|
|
@@ -275,23 +226,22 @@ async def manage_mcp_servers():
|
|
275
226
|
health = await resp.json()
|
276
227
|
print(f"Server status: {health['status']}")
|
277
228
|
|
278
|
-
# Get
|
229
|
+
# Get configured servers
|
279
230
|
async with session.get(
|
280
|
-
"http://localhost:3001/mcp/status"
|
281
|
-
headers=headers
|
231
|
+
"http://localhost:3001/mcp/status"
|
282
232
|
) as resp:
|
283
233
|
status = await resp.json()
|
284
|
-
print("
|
234
|
+
print("Configured servers:")
|
285
235
|
for server in status['servers']:
|
286
|
-
print(f"- {server['name']}
|
287
|
-
|
288
|
-
#
|
236
|
+
print(f"- {server['name']} (enabled={server['enabled']})")
|
237
|
+
|
238
|
+
# Mount a server
|
289
239
|
async with session.post(
|
290
|
-
"http://localhost:3001/mcp/filesystem
|
240
|
+
"http://localhost:3001/mcp/mount/filesystem",
|
291
241
|
headers=headers
|
292
242
|
) as resp:
|
293
243
|
result = await resp.json()
|
294
|
-
print(f"
|
244
|
+
print(f"Mount result: {result}")
|
295
245
|
|
296
246
|
asyncio.run(manage_mcp_servers())
|
297
247
|
```
|
@@ -313,20 +263,20 @@ async function manageMCPServers() {
|
|
313
263
|
const health = await axios.get(`${API_BASE}/health`);
|
314
264
|
console.log('Server status:', health.data.status);
|
315
265
|
|
316
|
-
// Get
|
317
|
-
const status = await axios.get(`${API_BASE}/mcp/status
|
318
|
-
console.log('
|
266
|
+
// Get configured servers
|
267
|
+
const status = await axios.get(`${API_BASE}/mcp/status`);
|
268
|
+
console.log('Configured servers:');
|
319
269
|
status.data.servers.forEach(server => {
|
320
|
-
console.log(`- ${server.name}
|
270
|
+
console.log(`- ${server.name} (enabled=${server.enabled})`);
|
321
271
|
});
|
322
|
-
|
323
|
-
//
|
324
|
-
const
|
325
|
-
`${API_BASE}/mcp/filesystem
|
272
|
+
|
273
|
+
// Mount filesystem server
|
274
|
+
const mount = await axios.post(
|
275
|
+
`${API_BASE}/mcp/mount/filesystem`,
|
326
276
|
{},
|
327
277
|
{ headers }
|
328
278
|
);
|
329
|
-
console.log('
|
279
|
+
console.log('Mount result:', mount.data);
|
330
280
|
|
331
281
|
} catch (error) {
|
332
282
|
console.error('Error:', error.response?.data || error.message);
|
@@ -359,13 +309,13 @@ curl -s "$BASE_URL/health" | jq .
|
|
359
309
|
echo "Getting MCP server status..."
|
360
310
|
api_call "$BASE_URL/mcp/status" | jq .
|
361
311
|
|
362
|
-
#
|
363
|
-
echo "
|
364
|
-
api_call -X POST "$BASE_URL/mcp/filesystem
|
312
|
+
# Mount filesystem server
|
313
|
+
echo "Mounting filesystem server..."
|
314
|
+
api_call -X POST "$BASE_URL/mcp/mount/filesystem" | jq .
|
365
315
|
|
366
|
-
# Check
|
367
|
-
echo "
|
368
|
-
api_call "$BASE_URL/mcp/
|
316
|
+
# Check mounted
|
317
|
+
echo "Getting mounted servers..."
|
318
|
+
api_call "$BASE_URL/mcp/mounted" | jq .
|
369
319
|
```
|
370
320
|
|
371
321
|
## Use Cases
|
@@ -396,17 +346,17 @@ import aiohttp
|
|
396
346
|
async def enable_work_servers():
|
397
347
|
headers = {"Authorization": "Bearer work-api-key"}
|
398
348
|
|
399
|
-
#
|
349
|
+
# Mount work-related servers
|
400
350
|
work_servers = ["github", "documents", "slack-integration"]
|
401
351
|
|
402
352
|
async with aiohttp.ClientSession() as session:
|
403
353
|
for server in work_servers:
|
404
354
|
async with session.post(
|
405
|
-
f"http://localhost:3001/mcp/{server}
|
355
|
+
f"http://localhost:3001/mcp/mount/{server}",
|
406
356
|
headers=headers
|
407
357
|
) as resp:
|
408
358
|
result = await resp.json()
|
409
|
-
print(f"
|
359
|
+
print(f"Mounted {server}: {result}")
|
410
360
|
```
|
411
361
|
|
412
362
|
### 3. Server Health Monitoring
|
@@ -430,10 +380,10 @@ async def monitor_servers():
|
|
430
380
|
status = await resp.json()
|
431
381
|
|
432
382
|
for server in status['servers']:
|
433
|
-
|
434
|
-
|
383
|
+
# Example: ensure critical servers are mounted
|
384
|
+
if server['enabled'] and server['name'] == 'filesystem':
|
435
385
|
await session.post(
|
436
|
-
f"http://localhost:3001/mcp/{server['name']}
|
386
|
+
f"http://localhost:3001/mcp/mount/{server['name']}",
|
437
387
|
headers=headers
|
438
388
|
)
|
439
389
|
|
@@ -452,8 +402,8 @@ asyncio.run(monitor_servers())
|
|
452
402
|
# Check if command exists
|
453
403
|
which uvx
|
454
404
|
|
455
|
-
# Check configuration
|
456
|
-
python -c "from src.config import
|
405
|
+
# Check configuration load
|
406
|
+
python -c "from src.config import Config; print(Config().mcp_servers[0].command)"
|
457
407
|
|
458
408
|
# Check logs
|
459
409
|
tail -f server.log
|
@@ -485,9 +435,9 @@ asyncio.run(monitor_servers())
|
|
485
435
|
# Check server status
|
486
436
|
curl -H "Authorization: Bearer api-key" http://localhost:3001/mcp/status
|
487
437
|
|
488
|
-
#
|
438
|
+
# Remount server by name
|
489
439
|
curl -X POST -H "Authorization: Bearer api-key" \
|
490
|
-
http://localhost:3001/mcp/server-name
|
440
|
+
http://localhost:3001/mcp/mount/server-name
|
491
441
|
```
|
492
442
|
|
493
443
|
### Debug Mode
|
@@ -16,7 +16,10 @@ make docker_build
|
|
16
16
|
make docker_run
|
17
17
|
```
|
18
18
|
|
19
|
-
|
19
|
+
Services:
|
20
|
+
|
21
|
+
- MCP protocol server: `http://localhost:3000/mcp/`
|
22
|
+
- Management API + dashboard: `http://localhost:3001`
|
20
23
|
|
21
24
|
## Manual Docker Commands
|
22
25
|
|
@@ -58,7 +58,7 @@ pip install -r requirements.lock
|
|
58
58
|
make setup
|
59
59
|
|
60
60
|
# Or manually
|
61
|
-
python -c "from src.config import Config; Config.create_default().save()"
|
61
|
+
python -c "from src.config import Config; cfg=Config(); cfg.create_default(); cfg.save()"
|
62
62
|
```
|
63
63
|
|
64
64
|
### 4. Configure
|
@@ -104,8 +104,8 @@ make sync
|
|
104
104
|
# Setup configuration
|
105
105
|
make setup
|
106
106
|
|
107
|
-
# Run
|
108
|
-
make
|
107
|
+
# Run the server
|
108
|
+
make run
|
109
109
|
|
110
110
|
# Run tests
|
111
111
|
make test
|
@@ -124,12 +124,11 @@ make ci
|
|
124
124
|
# Start server
|
125
125
|
make run
|
126
126
|
|
127
|
-
# Health check
|
128
|
-
curl http://localhost:
|
127
|
+
# Health check (API)
|
128
|
+
curl http://localhost:3001/health
|
129
129
|
|
130
|
-
# Check MCP server status (
|
131
|
-
curl
|
132
|
-
http://localhost:3000/mcp/status
|
130
|
+
# Check MCP server status (public)
|
131
|
+
curl http://localhost:3001/mcp/status
|
133
132
|
```
|
134
133
|
|
135
134
|
## Configuration
|