open-edison 0.1.30__py3-none-any.whl → 0.1.34__py3-none-any.whl

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.
@@ -10,7 +10,7 @@
10
10
  const prefersLight = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches;
11
11
  document.documentElement.setAttribute('data-theme', prefersLight ? 'light' : 'dark');
12
12
  </script>
13
- <script type="module" crossorigin src="/assets/index-DOR5YaNc.js"></script>
13
+ <script type="module" crossorigin src="/assets/index-BUUcUfTt.js"></script>
14
14
  <link rel="stylesheet" crossorigin href="/assets/index-o6_8mdM8.css">
15
15
  </head>
16
16
 
src/server.py CHANGED
@@ -127,15 +127,22 @@ class OpenEdisonProxy:
127
127
  app.add_api_route("/favicon.ico", _favicon, methods=["GET"]) # type: ignore[arg-type]
128
128
  log.info(f"📊 Dashboard static assets mounted at /dashboard from {static_dir}")
129
129
  else:
130
- # Emit a more detailed diagnostic and fail fast when assets are not found
130
+ # If running from an installed package (no repository indicators), fail fast.
131
+ # If running from repository source (pyproject present alongside src/), skip mount.
131
132
  cwd = Path.cwd()
132
- msg = (
133
- "Packaged dashboard assets not found. Expected at one of: "
134
- f"{primary_candidate} or {secondary_candidate}. "
135
- f"cwd={cwd}, __file__={Path(__file__).resolve()}"
133
+ repo_root_candidate = Path(__file__).parent.parent / "pyproject.toml"
134
+ if not repo_root_candidate.exists():
135
+ msg = (
136
+ "Packaged dashboard assets not found. Expected at one of: "
137
+ f"{primary_candidate} or {secondary_candidate}. "
138
+ f"cwd={cwd}, __file__={Path(__file__).resolve()}"
139
+ )
140
+ log.error(msg)
141
+ raise RuntimeError(msg)
142
+ log.debug(
143
+ "Repository source detected ({} present). Skipping dashboard mount.",
144
+ repo_root_candidate,
136
145
  )
137
- log.error(msg)
138
- raise RuntimeError(msg)
139
146
  except Exception as mount_err: # noqa: BLE001
140
147
  log.error(f"Failed to mount dashboard static assets: {mount_err}")
141
148
  raise
@@ -956,6 +963,7 @@ class OpenEdisonProxy:
956
963
  scopes=scopes,
957
964
  client_name=client_name or "OpenEdison MCP Gateway",
958
965
  token_storage_cache_dir=oauth_manager.cache_dir,
966
+ callback_port=50001,
959
967
  )
960
968
 
961
969
  # Create a temporary client and test the connection
src/single_user_mcp.py CHANGED
@@ -278,6 +278,27 @@ class SingleUserMCP(FastMCP[Any]):
278
278
  log.info(f"🧹 Unmounted server {server_name} and cleared references")
279
279
  return True
280
280
 
281
+ async def _send_list_changed_notifications(self) -> None:
282
+ """Send notifications to clients about changed component lists."""
283
+ try:
284
+ # Import here to avoid circular imports
285
+ from fastmcp.server.dependencies import get_context
286
+
287
+ try:
288
+ context = get_context()
289
+ # Queue notifications for all component types since we don't know
290
+ # what types of components the unmounted server provided
291
+ context._queue_tool_list_changed() # type: ignore
292
+ context._queue_resource_list_changed() # type: ignore
293
+ context._queue_prompt_list_changed() # type: ignore
294
+ log.debug("Queued component list change notifications")
295
+ except RuntimeError:
296
+ # No active context - notifications will be sent when context becomes available
297
+ log.debug("No active context for notifications")
298
+
299
+ except Exception as e:
300
+ log.warning(f"Error sending unmount notifications: {e}")
301
+
281
302
  async def initialize(self) -> None:
282
303
  """Initialize the FastMCP server using unified composite proxy approach."""
283
304
  log.info("Initializing Single User MCP server with composite proxy")
@@ -306,6 +327,9 @@ class SingleUserMCP(FastMCP[Any]):
306
327
  _ = await self._resource_manager.list_resources()
307
328
  _ = await self._prompt_manager.list_prompts()
308
329
 
330
+ # Send notifications to clients about changed component lists
331
+ await self._send_list_changed_notifications()
332
+
309
333
  def _calculate_risk_level(self, trifecta: dict[str, bool]) -> str:
310
334
  """
311
335
  Calculate a human-readable risk level based on trifecta flags.