proxy runtime to get this thing now

the merge is still merging
This commit is contained in:
lda
2026-05-13 18:44:32 +07:00 Verified
parent 7723d8558e
commit 92f5ca1755
6 changed files with 94 additions and 9 deletions
+2 -1
View File
@@ -24,6 +24,7 @@ def create_unified_proxy_server(
admin_tools: bool = True,
) -> FastMCP[Any]:
"""Create one MCP server with upstream proxy, admin, and workflow tools."""
service = build_service_from_config(config)
runtime = TransparentProxyRuntime(
config,
config_path=config_path,
@@ -31,8 +32,8 @@ def create_unified_proxy_server(
prompts_as_tools=prompts_as_tools,
search_tools=search_tools,
admin_tools=admin_tools,
event_bus=service.event_bus,
)
service = build_service_from_config(config)
_register_workflow_tools(runtime.server, WorkflowSurfaceHandlers(service))
return runtime.server
+5 -6
View File
@@ -5,8 +5,8 @@ from typing import Any
from fastmcp import Context, FastMCP
from ..admin_surface import ProxyAdminRuntime, TransparentAdminHandlers
from ..events import make_event
from ..notifications import FastMcpContextNotificationSink
from .reload_events import reload_change_events
def create_proxy_admin_server(
@@ -48,7 +48,7 @@ def create_proxy_admin_server(
)
async def reload_config(ctx: Context) -> dict[str, Any]:
result = handlers.reload_config()
await _send_reload_notifications(ctx)
await _send_reload_notifications(ctx, result)
return result
@admin.tool(
@@ -140,9 +140,8 @@ def create_proxy_admin_server(
return admin
async def _send_reload_notifications(ctx: Context) -> None:
async def _send_reload_notifications(ctx: Context, result: dict[str, Any]) -> None:
"""Notify the current client that reload may have changed visible capabilities."""
sink = FastMcpContextNotificationSink(ctx)
await sink.send_event(make_event("tools_changed"))
await sink.send_event(make_event("resources_changed"))
await sink.send_event(make_event("prompts_changed"))
for event in reload_change_events(result):
await sink.send_event(event)
@@ -0,0 +1,24 @@
from __future__ import annotations
from typing import Any
from ..events import McpEvent, make_event
def reload_change_events(result: dict[str, Any]) -> list[McpEvent]:
"""Build local change events for a successful proxy runtime reload."""
event_payload = {
"reason": "transparent_reload",
"mounted_connections": result["mounted_connections"],
"connection_count": result["connection_count"],
"enabled_connection_count": result["enabled_connection_count"],
}
return [
make_event(kind, payload=event_payload)
for kind in (
"tools_changed",
"resources_changed",
"prompts_changed",
"catalog_changed",
)
]
+19 -1
View File
@@ -12,6 +12,7 @@ from fastmcp.server.transforms import Namespace, PromptsAsTools, ResourcesAsTool
from fastmcp.server.transforms.search import BM25SearchTransform
from ..control import BrokerConfigManager, ConfigMutationError
from ..events import EventBus
from ..models import BrokerConfig
from ..shared.names import ADMIN_NAMESPACE, LdaNamespace
from ..proxy_config import broker_config_to_fastmcp_config
@@ -22,6 +23,7 @@ from .tools import (
filter_proxy_tools,
proxy_tools_page,
)
from .reload_events import reload_change_events
_ADMIN_TOOL_NAMES = [
f"{ADMIN_NAMESPACE}.list_connections",
@@ -48,6 +50,7 @@ class TransparentProxyRuntime:
prompts_as_tools: bool = False,
search_tools: bool = False,
admin_tools: bool = True,
event_bus: EventBus | None = None,
) -> None:
self.config = config
self.manager = None if config_path is None else BrokerConfigManager(config_path)
@@ -60,6 +63,7 @@ class TransparentProxyRuntime:
),
)
self.admin_tools = admin_tools
self.event_bus = event_bus
self.reload()
if resources_as_tools:
self.server.add_transform(ResourcesAsTools(self.server))
@@ -107,13 +111,22 @@ class TransparentProxyRuntime:
self.server.mount(proxy)
mounted_connections.append(connection.id)
return {
result = {
"ok": True,
"reloaded": True,
"mounted_connections": mounted_connections,
"connection_count": len(config.connections),
"enabled_connection_count": len(mounted_connections),
}
self._publish_reload_events(result)
return result
def _publish_reload_events(self, result: dict[str, Any]) -> None:
"""Publish local change events after a successful best-effort remount."""
if self.event_bus is None:
return
for event in reload_change_events(result):
self.event_bus.publish(event)
async def list_proxy_tools(self) -> list[dict[str, Any]]:
return await self._list_proxy_tools()
@@ -171,6 +184,7 @@ def create_transparent_proxy_server(
prompts_as_tools: bool = False,
search_tools: bool = False,
admin_tools: bool = True,
event_bus: EventBus | None = None,
) -> FastMCP[Any]:
validate_transparent_proxy_config(
config,
@@ -184,6 +198,7 @@ def create_transparent_proxy_server(
prompts_as_tools=prompts_as_tools,
search_tools=search_tools,
admin_tools=admin_tools,
event_bus=event_bus,
).server
@@ -195,6 +210,7 @@ def create_transparent_proxy_client(
prompts_as_tools: bool = False,
search_tools: bool = False,
admin_tools: bool = True,
event_bus: EventBus | None = None,
) -> Client[FastMCPTransport]:
return Client(
FastMCPTransport(
@@ -205,6 +221,8 @@ def create_transparent_proxy_client(
prompts_as_tools=prompts_as_tools,
search_tools=search_tools,
admin_tools=admin_tools,
event_bus=event_bus,
)
)
)