open-edison 0.1.41__tar.gz → 0.1.43__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.
Files changed (54) hide show
  1. {open_edison-0.1.41 → open_edison-0.1.43}/PKG-INFO +1 -1
  2. {open_edison-0.1.41 → open_edison-0.1.43}/pyproject.toml +1 -2
  3. {open_edison-0.1.41 → open_edison-0.1.43}/src/cli.py +6 -33
  4. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/api.py +28 -20
  5. {open_edison-0.1.41 → open_edison-0.1.43}/.gitignore +0 -0
  6. {open_edison-0.1.41 → open_edison-0.1.43}/LICENSE +0 -0
  7. {open_edison-0.1.41 → open_edison-0.1.43}/README.md +0 -0
  8. {open_edison-0.1.41 → open_edison-0.1.43}/config.json +0 -0
  9. {open_edison-0.1.41 → open_edison-0.1.43}/desktop_ext/README.md +0 -0
  10. {open_edison-0.1.41 → open_edison-0.1.43}/docs/README.md +0 -0
  11. {open_edison-0.1.41 → open_edison-0.1.43}/docs/architecture/single_user_design.md +0 -0
  12. {open_edison-0.1.41 → open_edison-0.1.43}/docs/core/configuration.md +0 -0
  13. {open_edison-0.1.41 → open_edison-0.1.43}/docs/core/project_structure.md +0 -0
  14. {open_edison-0.1.41 → open_edison-0.1.43}/docs/core/proxy_usage.md +0 -0
  15. {open_edison-0.1.41 → open_edison-0.1.43}/docs/deployment/docker.md +0 -0
  16. {open_edison-0.1.41 → open_edison-0.1.43}/docs/deployment/local.md +0 -0
  17. {open_edison-0.1.41 → open_edison-0.1.43}/docs/development/contributing.md +0 -0
  18. {open_edison-0.1.41 → open_edison-0.1.43}/docs/development/development_guide.md +0 -0
  19. {open_edison-0.1.41 → open_edison-0.1.43}/docs/development/testing.md +0 -0
  20. {open_edison-0.1.41 → open_edison-0.1.43}/docs/quick-reference/api_reference.md +0 -0
  21. {open_edison-0.1.41 → open_edison-0.1.43}/docs/quick-reference/config_quick_start.md +0 -0
  22. {open_edison-0.1.41 → open_edison-0.1.43}/hatch_build.py +0 -0
  23. {open_edison-0.1.41 → open_edison-0.1.43}/installation_test/README.md +0 -0
  24. {open_edison-0.1.41 → open_edison-0.1.43}/prompt_permissions.json +0 -0
  25. {open_edison-0.1.41 → open_edison-0.1.43}/resource_permissions.json +0 -0
  26. {open_edison-0.1.41 → open_edison-0.1.43}/src/__init__.py +0 -0
  27. {open_edison-0.1.41 → open_edison-0.1.43}/src/__main__.py +0 -0
  28. {open_edison-0.1.41 → open_edison-0.1.43}/src/config.py +0 -0
  29. {open_edison-0.1.41 → open_edison-0.1.43}/src/config.pyi +0 -0
  30. {open_edison-0.1.41 → open_edison-0.1.43}/src/events.py +0 -0
  31. {open_edison-0.1.41 → open_edison-0.1.43}/src/frontend_dist/assets/index-BUUcUfTt.js +0 -0
  32. {open_edison-0.1.41 → open_edison-0.1.43}/src/frontend_dist/assets/index-o6_8mdM8.css +0 -0
  33. {open_edison-0.1.41 → open_edison-0.1.43}/src/frontend_dist/index.html +0 -0
  34. {open_edison-0.1.41 → open_edison-0.1.43}/src/frontend_dist/sw.js +0 -0
  35. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/__init__.py +0 -0
  36. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/__main__.py +0 -0
  37. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/cli.py +0 -0
  38. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/export_cli.py +0 -0
  39. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/exporters.py +0 -0
  40. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/import_api.py +0 -0
  41. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/importers.py +0 -0
  42. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/merge.py +0 -0
  43. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/parsers.py +0 -0
  44. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/paths.py +0 -0
  45. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/quick_cli.py +0 -0
  46. {open_edison-0.1.41 → open_edison-0.1.43}/src/mcp_importer/types.py +0 -0
  47. {open_edison-0.1.41 → open_edison-0.1.43}/src/middleware/data_access_tracker.py +0 -0
  48. {open_edison-0.1.41 → open_edison-0.1.43}/src/middleware/session_tracking.py +0 -0
  49. {open_edison-0.1.41 → open_edison-0.1.43}/src/oauth_manager.py +0 -0
  50. {open_edison-0.1.41 → open_edison-0.1.43}/src/permissions.py +0 -0
  51. {open_edison-0.1.41 → open_edison-0.1.43}/src/server.py +0 -0
  52. {open_edison-0.1.41 → open_edison-0.1.43}/src/single_user_mcp.py +0 -0
  53. {open_edison-0.1.41 → open_edison-0.1.43}/src/telemetry.py +0 -0
  54. {open_edison-0.1.41 → open_edison-0.1.43}/tool_permissions.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: open-edison
3
- Version: 0.1.41
3
+ Version: 0.1.43
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "open-edison"
3
- version = "0.1.41"
3
+ version = "0.1.43"
4
4
  description = "Open-source MCP security, aggregation, and monitoring. Single-user, self-hosted MCP proxy."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -64,7 +64,6 @@ include = [
64
64
  "prompt_permissions.json",
65
65
  "docs/**",
66
66
  ]
67
- force-include = { "src/frontend_dist" = "frontend_dist" }
68
67
 
69
68
  [tool.hatch.build.targets.wheel.hooks.custom]
70
69
  path = "hatch_build.py"
@@ -8,15 +8,15 @@ import argparse
8
8
  import asyncio
9
9
  import os
10
10
  import subprocess as _subprocess
11
- import sys
12
11
  from contextlib import suppress
13
12
  from pathlib import Path
14
- from typing import Any, NoReturn, cast
13
+ from typing import Any, NoReturn
15
14
 
16
15
  from loguru import logger as _log # type: ignore[reportMissingImports]
17
16
 
18
- from .config import Config, get_config_dir, get_config_json_path
19
- from .server import OpenEdisonProxy
17
+ from src.config import Config, get_config_dir, get_config_json_path
18
+ from src.mcp_importer.cli import run_cli
19
+ from src.server import OpenEdisonProxy
20
20
 
21
21
  log: Any = _log
22
22
 
@@ -220,35 +220,8 @@ def main(argv: list[str] | None = None) -> NoReturn: # noqa: C901
220
220
  raise SystemExit(exit_code)
221
221
 
222
222
  if getattr(args, "command", None) == "import-mcp":
223
- # Defer-import importer package (lives under repository scripts/)
224
- importer_pkg = Path(__file__).parent.parent / "scripts" / "mcp_importer"
225
- try:
226
- if str(importer_pkg) not in sys.path:
227
- sys.path.insert(0, str(importer_pkg))
228
- from mcp_importer.cli import run_cli # type: ignore
229
- except Exception as imp_exc: # noqa: BLE001
230
- log.error(
231
- "Failed to load MCP importer package from {}: {}",
232
- importer_pkg,
233
- imp_exc,
234
- )
235
- raise SystemExit(1) from imp_exc
236
-
237
- importer_argv: list[str] = []
238
- if args.source:
239
- importer_argv += ["--source", str(args.source)]
240
- if getattr(args, "config_dir", None):
241
- importer_argv += [
242
- "--config-dir",
243
- str(Path(args.config_dir).expanduser().resolve()),
244
- ]
245
- if args.merge:
246
- importer_argv += ["--merge", str(args.merge)]
247
- if bool(getattr(args, "dry_run", False)):
248
- importer_argv += ["--dry-run"]
249
-
250
- rc_val: int = int(cast(Any, run_cli)(importer_argv))
251
- raise SystemExit(rc_val)
223
+ result_code = run_cli(argv)
224
+ raise SystemExit(result_code)
252
225
 
253
226
  # default: run server (top-level flags)
254
227
  try:
@@ -3,9 +3,10 @@ import asyncio
3
3
  from collections.abc import Awaitable
4
4
  from enum import Enum
5
5
  from pathlib import Path
6
- from typing import Any, Protocol, cast, runtime_checkable
6
+ from typing import Any
7
7
 
8
8
  from fastmcp import FastMCP
9
+ from loguru import logger as log
9
10
 
10
11
  from src.config import Config, MCPServerConfig, get_config_json_path
11
12
  from src.mcp_importer import paths as _paths
@@ -24,14 +25,6 @@ from src.mcp_importer.merge import MergePolicy, merge_servers
24
25
  from src.oauth_manager import OAuthStatus, get_oauth_manager
25
26
 
26
27
 
27
- @runtime_checkable
28
- class _MCPClientLike(Protocol):
29
- async def list_tools(self) -> Any: ...
30
- async def list_resources(self) -> Any: ...
31
- async def list_prompts(self) -> Any: ...
32
- def shutdown(self) -> Awaitable[Any] | Any: ...
33
-
34
-
35
28
  class CLIENT(str, Enum):
36
29
  CURSOR = "cursor"
37
30
  VSCODE = "vscode"
@@ -144,6 +137,7 @@ def verify_mcp_server(server: MCPServerConfig) -> bool: # noqa
144
137
  if not server.command.strip():
145
138
  return False
146
139
 
140
+ # Inline backend config and capability listing (no extra helpers)
147
141
  backend_cfg: dict[str, Any] = {
148
142
  "mcpServers": {
149
143
  server.name: {
@@ -156,26 +150,40 @@ def verify_mcp_server(server: MCPServerConfig) -> bool: # noqa
156
150
  }
157
151
 
158
152
  proxy: FastMCP[Any] | None = None
153
+ host: FastMCP[Any] | None = None
159
154
  try:
160
- proxy = FastMCP.as_proxy(backend=backend_cfg, name=f"open-edison-verify-{server.name}")
161
- s: _MCPClientLike = cast(_MCPClientLike, proxy)
155
+ proxy = FastMCP.as_proxy(backend_cfg)
156
+ host = FastMCP(name=f"open-edison-verify-host-{server.name}")
157
+ host.mount(proxy, prefix=server.name)
158
+
159
+ async def _call_list(kind: str) -> Any:
160
+ manager_name = {
161
+ "tools": "_tool_manager",
162
+ "resources": "_resource_manager",
163
+ "prompts": "_prompt_manager",
164
+ }[kind]
165
+ manager = getattr(host, manager_name)
166
+ return await getattr(manager, f"list_{kind}")()
167
+
162
168
  await asyncio.wait_for(
163
169
  asyncio.gather(
164
- s.list_tools(),
165
- s.list_resources(),
166
- s.list_prompts(),
170
+ _call_list("tools"),
171
+ _call_list("resources"),
172
+ _call_list("prompts"),
167
173
  ),
168
- timeout=15.0,
174
+ timeout=30.0,
169
175
  )
170
176
  return True
171
- except Exception:
177
+ except Exception as e:
178
+ log.error("MCP verification failed for '{}': {}", server.name, e)
172
179
  return False
173
180
  finally:
174
181
  try:
175
- if isinstance(proxy, FastMCP):
176
- result = proxy.shutdown() # type: ignore[attr-defined]
177
- if isinstance(result, Awaitable):
178
- await result # type: ignore[func-returns-value]
182
+ for obj in (host, proxy):
183
+ if isinstance(obj, FastMCP):
184
+ result = obj.shutdown() # type: ignore[attr-defined]
185
+ if isinstance(result, Awaitable):
186
+ await result # type: ignore[func-returns-value]
179
187
  except Exception:
180
188
  pass
181
189
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes