open-edison 0.1.30__tar.gz → 0.1.36__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.30 → open_edison-0.1.36}/PKG-INFO +3 -7
- {open_edison-0.1.30 → open_edison-0.1.36}/README.md +2 -2
- {open_edison-0.1.30 → open_edison-0.1.36}/config.json +21 -18
- {open_edison-0.1.30 → open_edison-0.1.36}/desktop_ext/README.md +9 -11
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/development/contributing.md +2 -1
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/development/development_guide.md +1 -1
- {open_edison-0.1.30 → open_edison-0.1.36}/hatch_build.py +9 -2
- open_edison-0.1.36/installation_test/README.md +18 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/pyproject.toml +15 -8
- {open_edison-0.1.30 → open_edison-0.1.36}/src/cli.py +2 -16
- {open_edison-0.1.30 → open_edison-0.1.36}/src/config.py +20 -2
- open_edison-0.1.36/src/config.pyi +80 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/events.py +0 -2
- open_edison-0.1.36/src/frontend_dist/assets/index-BUUcUfTt.js +51 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/frontend_dist/index.html +1 -1
- {open_edison-0.1.30 → open_edison-0.1.36}/src/server.py +17 -9
- {open_edison-0.1.30 → open_edison-0.1.36}/src/single_user_mcp.py +24 -0
- open_edison-0.1.30/src/frontend_dist/assets/index-DOR5YaNc.js +0 -51
- {open_edison-0.1.30 → open_edison-0.1.36}/.gitignore +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/LICENSE +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/README.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/architecture/single_user_design.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/core/configuration.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/core/project_structure.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/core/proxy_usage.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/deployment/docker.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/deployment/local.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/development/testing.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/quick-reference/api_reference.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/docs/quick-reference/config_quick_start.md +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/prompt_permissions.json +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/resource_permissions.json +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/__init__.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/__main__.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/frontend_dist/assets/index-o6_8mdM8.css +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/frontend_dist/sw.js +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/middleware/data_access_tracker.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/middleware/session_tracking.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/oauth_manager.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/permissions.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/src/telemetry.py +0 -0
- {open_edison-0.1.30 → open_edison-0.1.36}/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.36
|
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
|
@@ -20,17 +20,13 @@ Requires-Dist: pyyaml>=6.0.2
|
|
20
20
|
Requires-Dist: sqlalchemy>=2.0.41
|
21
21
|
Requires-Dist: starlette>=0.47.1
|
22
22
|
Requires-Dist: uvicorn>=0.35.0
|
23
|
-
Provides-Extra: dev
|
24
|
-
Requires-Dist: pytest-asyncio>=1.0.0; extra == 'dev'
|
25
|
-
Requires-Dist: pytest>=8.3.3; extra == 'dev'
|
26
|
-
Requires-Dist: ruff>=0.12.3; extra == 'dev'
|
27
23
|
Description-Content-Type: text/markdown
|
28
24
|
|
29
25
|
# OpenEdison 🔒⚡️
|
30
26
|
|
31
|
-
> The
|
27
|
+
> The Secure MCP Control Panel
|
32
28
|
|
33
|
-
Connect AI to your data/software securely without risk of data exfiltration. Gain visibility, block threats, and get alerts on the data your agent is reading/writing.
|
29
|
+
Connect AI to your data/software securely without risk of data exfiltration. Gain visibility, block threats, and get alerts on the data your agent is reading/writing.
|
34
30
|
|
35
31
|
OpenEdison solves the [lethal trifecta problem](https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/), which can cause agent hijacking & data exfiltration by malicious actors.
|
36
32
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# OpenEdison 🔒⚡️
|
2
2
|
|
3
|
-
> The
|
3
|
+
> The Secure MCP Control Panel
|
4
4
|
|
5
|
-
Connect AI to your data/software securely without risk of data exfiltration. Gain visibility, block threats, and get alerts on the data your agent is reading/writing.
|
5
|
+
Connect AI to your data/software securely without risk of data exfiltration. Gain visibility, block threats, and get alerts on the data your agent is reading/writing.
|
6
6
|
|
7
7
|
OpenEdison solves the [lethal trifecta problem](https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/), which can cause agent hijacking & data exfiltration by malicious actors.
|
8
8
|
|
@@ -59,26 +59,14 @@
|
|
59
59
|
},
|
60
60
|
{
|
61
61
|
"name": "supabase",
|
62
|
-
"command": "",
|
63
|
-
"args": [],
|
64
|
-
"env": {
|
65
|
-
"SUPABASE_URL": "https://your-supabase-url.supabase.co",
|
66
|
-
"SUPABASE_API_KEY": "your-supabase-api-key",
|
67
|
-
"SUPABASE_DATABASE": "your-database-name"
|
68
|
-
},
|
69
|
-
"enabled": false
|
70
|
-
},
|
71
|
-
{
|
72
|
-
"name": "google_drive",
|
73
62
|
"command": "npx",
|
74
63
|
"args": [
|
75
64
|
"-y",
|
76
|
-
"@
|
65
|
+
"@supabase/mcp-server"
|
77
66
|
],
|
78
67
|
"env": {
|
79
|
-
"
|
80
|
-
"
|
81
|
-
"GOOGLE_REFRESH_TOKEN": "your-refresh-token"
|
68
|
+
"SUPABASE_URL": "https://YOUR_PROJECT.supabase.co",
|
69
|
+
"SUPABASE_ANON_KEY": "your-supabase-anon-key"
|
82
70
|
},
|
83
71
|
"enabled": false
|
84
72
|
},
|
@@ -93,17 +81,32 @@
|
|
93
81
|
"env": {},
|
94
82
|
"enabled": false
|
95
83
|
},
|
84
|
+
{
|
85
|
+
"name": "google_drive",
|
86
|
+
"command": "npx",
|
87
|
+
"args": [
|
88
|
+
"-y",
|
89
|
+
"@modelcontextprotocol/server-gdrive"
|
90
|
+
],
|
91
|
+
"env": {
|
92
|
+
"GOOGLE_CLIENT_ID": "your-client-id",
|
93
|
+
"GOOGLE_CLIENT_SECRET": "your-client-secret",
|
94
|
+
"GOOGLE_REFRESH_TOKEN": "your-refresh-token"
|
95
|
+
},
|
96
|
+
"enabled": false
|
97
|
+
},
|
96
98
|
{
|
97
99
|
"name": "zapier",
|
98
100
|
"command": "npx",
|
99
101
|
"args": [
|
100
102
|
"-y",
|
101
103
|
"mcp-remote",
|
102
|
-
"https://mcp.zapier.com/api/mcp/s/
|
104
|
+
"https://mcp.zapier.com/api/mcp/s/REPLACE_WITH_ACCESS_TOKEN/mcp",
|
105
|
+
"--header",
|
106
|
+
"Accept: application/json, text/event-stream"
|
103
107
|
],
|
104
108
|
"env": {},
|
105
|
-
"enabled": false
|
106
|
-
"roots": []
|
109
|
+
"enabled": false
|
107
110
|
}
|
108
111
|
]
|
109
112
|
}
|
@@ -45,23 +45,21 @@ Access to all tools from MCP servers you've configured in Open Edison, such as:
|
|
45
45
|
3. **Go to Settings** → Extensions
|
46
46
|
4. **Click "Install Extension"** or drag the `.dxt` file into the window
|
47
47
|
5. **Configure your connection**:
|
48
|
-
- **Server URL**: Your Open Edison server MCP
|
49
|
-
- **API Key**: Your Open Edison API key
|
48
|
+
- **Server URL**: Your Open Edison server MCP endpoint (e.g., `http://localhost:3000/mcp/`)
|
49
|
+
- **API Key**: Your Open Edison API key (default for local dev: `dev-api-key-change-me`)
|
50
50
|
6. **Click "Install"** when prompted
|
51
51
|
7. **Done!** All your Open Edison tools are now available in Claude Desktop
|
52
52
|
|
53
|
-
### Server URL
|
53
|
+
### Server URL
|
54
54
|
|
55
|
-
-
|
56
|
-
- **Remote server**: `https://your-server.com:3001/mcp/call`
|
57
|
-
- **Docker deployment**: `http://your-docker-host:3001/mcp/call`
|
55
|
+
- `http://localhost:3000/mcp/`
|
58
56
|
|
59
57
|
## Configuration
|
60
58
|
|
61
59
|
### Required Settings
|
62
60
|
|
63
|
-
- **Server URL**: The full URL to your Open Edison MCP
|
64
|
-
- **API Key**: Your authentication key for the Open Edison server (configured in `config.json`)
|
61
|
+
- **Server URL**: The full URL to your Open Edison MCP endpoint (`http://localhost:3000/mcp/`)
|
62
|
+
- **API Key**: Your authentication key for the Open Edison server (configured in `config.json`; local default `dev-api-key-change-me`)
|
65
63
|
|
66
64
|
### Open Edison Server Setup
|
67
65
|
|
@@ -71,7 +69,7 @@ Make sure your Open Edison server is running and accessible:
|
|
71
69
|
2. **Configure MCP servers**: Edit `config.json` to add your MCP servers
|
72
70
|
3. **Set API key**: Ensure `server.api_key` is set in your `config.json`
|
73
71
|
|
74
|
-
Your server should be accessible at `http://localhost:
|
72
|
+
Your server should be accessible at `http://localhost:3000`.
|
75
73
|
|
76
74
|
## How It Works
|
77
75
|
|
@@ -129,10 +127,10 @@ This extension operates securely:
|
|
129
127
|
|
130
128
|
### Debug Steps
|
131
129
|
|
132
|
-
1. **Check server accessibility**: Try accessing `http://localhost:3001/health` in a browser
|
130
|
+
1. **Check server accessibility**: Try accessing `http://localhost:3001/health` (management API) in a browser
|
133
131
|
2. **Verify API key**: Check the `server.api_key` value in your Open Edison `config.json`
|
134
132
|
3. **Check logs**: Look at Claude Desktop logs for connection errors
|
135
|
-
4. **Test MCP endpoint**: Use curl to test the `/mcp
|
133
|
+
4. **Test MCP endpoint**: Use curl to test the `/mcp/` endpoint
|
136
134
|
|
137
135
|
### Log Locations
|
138
136
|
|
@@ -111,7 +111,8 @@ make test
|
|
111
111
|
|
112
112
|
**Standards**:
|
113
113
|
|
114
|
-
- **
|
114
|
+
- **uv** for formatting (`make format`)
|
115
|
+
- **Ruff** for linting (`make lint`)
|
115
116
|
- **Type hints** for all function signatures
|
116
117
|
- **Docstrings** for public functions and classes
|
117
118
|
|
@@ -413,7 +413,7 @@ from src.proxy import MCPProxy
|
|
413
413
|
|
414
414
|
### Code Style
|
415
415
|
|
416
|
-
- Use
|
416
|
+
- Use uv for formatting (`make format`) and Ruff for linting (`make lint`)
|
417
417
|
- Type hints for all function signatures
|
418
418
|
- Docstrings for all public functions/classes
|
419
419
|
|
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
import os
|
3
2
|
import shutil
|
4
3
|
from pathlib import Path
|
5
4
|
|
@@ -22,6 +21,14 @@ class BuildHook(BuildHookInterface): # type: ignore
|
|
22
21
|
src_frontend_dist = project_root / "src" / "frontend_dist"
|
23
22
|
repo_frontend_dist = project_root / "frontend" / "dist"
|
24
23
|
|
24
|
+
# Opt-in enforcement: only enforce when OPEN_EDISON_REQUIRE_FRONTEND=1/true/yes
|
25
|
+
enforce = os.environ.get("OPEN_EDISON_REQUIRE_FRONTEND", "").lower() in {"1", "true", "yes"}
|
26
|
+
if not enforce:
|
27
|
+
self.app.display_info(
|
28
|
+
"Skipping frontend_dist enforcement (set OPEN_EDISON_REQUIRE_FRONTEND=1 to enforce)"
|
29
|
+
)
|
30
|
+
return
|
31
|
+
|
25
32
|
# Fast path: already present in src/
|
26
33
|
if (src_frontend_dist / "index.html").exists():
|
27
34
|
self.app.display_info("frontend_dist already present; skipping build/copy")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Installation Test (Ubuntu)
|
2
|
+
|
3
|
+
This directory contains a Dockerfile that validates the README curl | bash installer on a clean Ubuntu environment.
|
4
|
+
|
5
|
+
How it works:
|
6
|
+
|
7
|
+
- Uses `ubuntu:24.04`
|
8
|
+
- Installs minimal prerequisites (`curl`, `ca-certificates`, etc.)
|
9
|
+
- Runs the documented installer: `curl -fsSL https://raw.githubusercontent.com/Edison-Watch/open-edison/main/curl_pipe_bash.sh | bash -s -- -h`
|
10
|
+
- The `-h` flag is forwarded to `open-edison`, so the installer prints help and exits 0, making the Docker build fast and non-interactive.
|
11
|
+
|
12
|
+
Build locally:
|
13
|
+
|
14
|
+
```bash
|
15
|
+
make install_curl_test
|
16
|
+
```
|
17
|
+
|
18
|
+
If the build completes successfully, the installer path is healthy. If it fails, the build will error and show logs with the failing step (e.g., uv install, Python 3.12, or `uvx open-edison`).
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "open-edison"
|
3
|
-
version = "0.1.
|
3
|
+
version = "0.1.36"
|
4
4
|
description = "Open-source MCP security, aggregation, and monitoring. Single-user, self-hosted MCP proxy."
|
5
5
|
readme = "README.md"
|
6
6
|
authors = [
|
@@ -42,14 +42,11 @@ dev-dependencies = [
|
|
42
42
|
"pytest-asyncio>=1.0.0",
|
43
43
|
"vulture>=2.11",
|
44
44
|
"twine>=5.1.1",
|
45
|
+
"ty>=0.0.1a19",
|
45
46
|
]
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
"ruff>=0.12.3",
|
50
|
-
"pytest>=8.3.3",
|
51
|
-
"pytest-asyncio>=1.0.0",
|
52
|
-
]
|
48
|
+
|
49
|
+
|
53
50
|
|
54
51
|
[tool.hatch.metadata]
|
55
52
|
allow-direct-references = true
|
@@ -67,7 +64,7 @@ include = [
|
|
67
64
|
"src/frontend_dist/**",
|
68
65
|
]
|
69
66
|
|
70
|
-
[tool.hatch.build.hooks.custom]
|
67
|
+
[tool.hatch.build.targets.wheel.hooks.custom]
|
71
68
|
path = "hatch_build.py"
|
72
69
|
|
73
70
|
|
@@ -85,6 +82,9 @@ include = [
|
|
85
82
|
]
|
86
83
|
force-include = { "src/frontend_dist" = "src/frontend_dist" }
|
87
84
|
|
85
|
+
[tool.hatch.build.targets.sdist.hooks.custom]
|
86
|
+
path = "hatch_build.py"
|
87
|
+
|
88
88
|
[tool.ruff]
|
89
89
|
line-length = 100
|
90
90
|
target-version = "py312"
|
@@ -116,5 +116,12 @@ reportUnusedFunction = false # Disable unused function warnings since we have m
|
|
116
116
|
venvPath = ".venv"
|
117
117
|
extraPaths = ["src"]
|
118
118
|
|
119
|
+
[tool.ty.rules]
|
120
|
+
possibly-unresolved-reference = "error"
|
121
|
+
index-out-of-bounds = "error"
|
122
|
+
|
123
|
+
[tool.ty.src]
|
124
|
+
exclude = ["tests/**"]
|
125
|
+
|
119
126
|
[tool.vulture]
|
120
127
|
exclude = ["tests", "src/frontend_dist"]
|
@@ -4,8 +4,6 @@ CLI entrypoint for Open Edison.
|
|
4
4
|
Provides `open-edison` executable when installed via pip/uvx/pipx.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from __future__ import annotations
|
8
|
-
|
9
7
|
import argparse
|
10
8
|
import asyncio
|
11
9
|
import os
|
@@ -17,7 +15,7 @@ from typing import Any, NoReturn, cast
|
|
17
15
|
|
18
16
|
from loguru import logger as _log # type: ignore[reportMissingImports]
|
19
17
|
|
20
|
-
from .config import Config, get_config_dir
|
18
|
+
from .config import Config, get_config_dir, get_config_json_path
|
21
19
|
from .server import OpenEdisonProxy
|
22
20
|
|
23
21
|
log: Any = _log
|
@@ -69,11 +67,6 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
|
69
67
|
default="interactive",
|
70
68
|
help="Source application to import from",
|
71
69
|
)
|
72
|
-
sp_import.add_argument(
|
73
|
-
"--project-dir",
|
74
|
-
type=Path,
|
75
|
-
help="When --source=cursor, path to the project containing .cursor/mcp.json",
|
76
|
-
)
|
77
70
|
sp_import.add_argument(
|
78
71
|
"--config-dir",
|
79
72
|
type=Path,
|
@@ -191,7 +184,7 @@ async def _run_server(args: Any) -> None:
|
|
191
184
|
config_dir = get_config_dir()
|
192
185
|
|
193
186
|
# Load config after setting env override
|
194
|
-
cfg = Config(
|
187
|
+
cfg = Config(get_config_json_path())
|
195
188
|
|
196
189
|
host = getattr(args, "host", None) or cfg.server.host
|
197
190
|
port = getattr(args, "port", None) or cfg.server.port
|
@@ -250,11 +243,6 @@ def main(argv: list[str] | None = None) -> NoReturn: # noqa: C901
|
|
250
243
|
importer_argv: list[str] = []
|
251
244
|
if args.source:
|
252
245
|
importer_argv += ["--source", str(args.source)]
|
253
|
-
if getattr(args, "project_dir", None):
|
254
|
-
importer_argv += [
|
255
|
-
"--project-dir",
|
256
|
-
str(Path(args.project_dir).expanduser().resolve()),
|
257
|
-
]
|
258
246
|
if getattr(args, "config_dir", None):
|
259
247
|
importer_argv += [
|
260
248
|
"--config-dir",
|
@@ -262,8 +250,6 @@ def main(argv: list[str] | None = None) -> NoReturn: # noqa: C901
|
|
262
250
|
]
|
263
251
|
if args.merge:
|
264
252
|
importer_argv += ["--merge", str(args.merge)]
|
265
|
-
if bool(getattr(args, "enable_imported", False)):
|
266
|
-
importer_argv += ["--enable-imported"]
|
267
253
|
if bool(getattr(args, "dry_run", False)):
|
268
254
|
importer_argv += ["--dry-run"]
|
269
255
|
|
@@ -142,11 +142,16 @@ class TelemetryConfig:
|
|
142
142
|
def load_json_file(path: Path) -> dict[str, Any]:
|
143
143
|
"""Load a JSON file from the given path.
|
144
144
|
Kept as a separate function because we want to manually clear cache sometimes (update in config)"""
|
145
|
-
log.
|
145
|
+
log.trace(f"Loading configuration from {path}")
|
146
146
|
with open(path) as f:
|
147
147
|
return json.load(f)
|
148
148
|
|
149
149
|
|
150
|
+
def clear_json_file_cache() -> None:
|
151
|
+
"""Clear the cache for the given JSON file path"""
|
152
|
+
load_json_file.cache_clear()
|
153
|
+
|
154
|
+
|
150
155
|
@dataclass
|
151
156
|
class Config:
|
152
157
|
"""Main configuration class"""
|
@@ -252,7 +257,20 @@ class Config:
|
|
252
257
|
}
|
253
258
|
|
254
259
|
# Ensure directory exists
|
255
|
-
|
260
|
+
try:
|
261
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
262
|
+
except FileExistsError as e:
|
263
|
+
# If the parent path exists as a file, not a directory, this will fail
|
264
|
+
if config_path.parent.is_file():
|
265
|
+
log.error(
|
266
|
+
f"Config directory path {config_path.parent} exists as a file, not a directory"
|
267
|
+
)
|
268
|
+
log.error("Please remove the file or specify a different config directory")
|
269
|
+
raise FileExistsError(
|
270
|
+
f"Config directory path {config_path.parent} exists as a file, not a directory"
|
271
|
+
) from e
|
272
|
+
log.error(f"Failed to create config directory {config_path.parent}: {e}")
|
273
|
+
raise
|
256
274
|
with open(config_path, "w") as f:
|
257
275
|
json.dump(data, f, indent=2)
|
258
276
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from typing import Any, overload
|
3
|
+
|
4
|
+
# Module constants
|
5
|
+
DEFAULT_OTLP_METRICS_ENDPOINT: str
|
6
|
+
root_dir: Path
|
7
|
+
|
8
|
+
def get_config_dir() -> Path: ...
|
9
|
+
def get_config_json_path() -> Path: ...
|
10
|
+
|
11
|
+
class ServerConfig:
|
12
|
+
host: str
|
13
|
+
port: int
|
14
|
+
api_key: str
|
15
|
+
|
16
|
+
class LoggingConfig:
|
17
|
+
level: str
|
18
|
+
database_path: str
|
19
|
+
|
20
|
+
class MCPServerConfig:
|
21
|
+
name: str
|
22
|
+
command: str
|
23
|
+
args: list[str]
|
24
|
+
env: dict[str, str] | None
|
25
|
+
enabled: bool
|
26
|
+
roots: list[str] | None
|
27
|
+
oauth_scopes: list[str] | None
|
28
|
+
oauth_client_name: str | None
|
29
|
+
|
30
|
+
def __init__(
|
31
|
+
self,
|
32
|
+
*,
|
33
|
+
name: str,
|
34
|
+
command: str,
|
35
|
+
args: list[str],
|
36
|
+
env: dict[str, str] | None = None,
|
37
|
+
enabled: bool = True,
|
38
|
+
roots: list[str] | None = None,
|
39
|
+
oauth_scopes: list[str] | None = None,
|
40
|
+
oauth_client_name: str | None = None,
|
41
|
+
) -> None: ...
|
42
|
+
def is_remote_server(self) -> bool: ...
|
43
|
+
def get_remote_url(self) -> str | None: ...
|
44
|
+
|
45
|
+
class TelemetryConfig:
|
46
|
+
enabled: bool
|
47
|
+
otlp_endpoint: str | None
|
48
|
+
headers: dict[str, str] | None
|
49
|
+
export_interval_ms: int
|
50
|
+
def __init__(
|
51
|
+
self,
|
52
|
+
*,
|
53
|
+
enabled: bool = True,
|
54
|
+
otlp_endpoint: str | None = None,
|
55
|
+
headers: dict[str, str] | None = None,
|
56
|
+
export_interval_ms: int = 60000,
|
57
|
+
) -> None: ...
|
58
|
+
|
59
|
+
def load_json_file(path: Path) -> dict[str, Any]: ...
|
60
|
+
def clear_json_file_cache() -> None: ...
|
61
|
+
|
62
|
+
class Config:
|
63
|
+
@property
|
64
|
+
def version(self) -> str: ...
|
65
|
+
server: ServerConfig
|
66
|
+
logging: LoggingConfig
|
67
|
+
mcp_servers: list[MCPServerConfig]
|
68
|
+
telemetry: TelemetryConfig | None
|
69
|
+
@overload
|
70
|
+
def __init__(self, config_path: Path | None = None) -> None: ...
|
71
|
+
@overload
|
72
|
+
def __init__(
|
73
|
+
self,
|
74
|
+
server: ServerConfig,
|
75
|
+
logging: LoggingConfig,
|
76
|
+
mcp_servers: list[MCPServerConfig],
|
77
|
+
telemetry: TelemetryConfig | None = None,
|
78
|
+
) -> None: ...
|
79
|
+
def save(self, config_path: Path | None = None) -> None: ...
|
80
|
+
def create_default(self) -> None: ...
|