2323from mcpm .monitor .event import trace_event
2424from mcpm .profile .profile_config import ProfileConfigManager
2525from mcpm .schemas .server_config import ServerConfig
26- from mcpm .utils .config import PROMPT_SPLITOR , RESOURCE_SPLITOR , RESOURCE_TEMPLATE_SPLITOR , TOOL_SPLITOR
26+ from mcpm .utils .config import (
27+ PROMPT_SPLITOR , RESOURCE_SPLITOR , RESOURCE_TEMPLATE_SPLITOR , TOOL_SPLITOR ,
28+ ConfigManager , DEFAULT_HOST , DEFAULT_PORT , DEFAULT_SHARE_ADDRESS
29+ )
2730
2831from .client_connection import ServerConnection
2932from .transport import RouterSseTransport
@@ -36,16 +39,42 @@ class MCPRouter:
3639 """
3740 A router that aggregates multiple MCP servers (SSE/STDIO) and
3841 exposes them as a single SSE server.
42+
43+ Example:
44+ ```python
45+ # Initialize with a custom API key
46+ router = MCPRouter(api_key="your-api-key")
47+
48+ # Initialize with custom router configuration
49+ router_config = {
50+ "host": "localhost",
51+ "port": 8080,
52+ "share_address": "custom.share.address:8080"
53+ }
54+ router = MCPRouter(api_key="your-api-key", router_config=router_config)
55+
56+ # Create a global config from the router's configuration
57+ router.create_global_config()
58+ ```
3959 """
4060
41- def __init__ (self , reload_server : bool = False , profile_path : str | None = None , strict : bool = False ) -> None :
61+ def __init__ (
62+ self ,
63+ reload_server : bool = False ,
64+ profile_path : str | None = None ,
65+ strict : bool = False ,
66+ api_key : str | None = None ,
67+ router_config : dict | None = None
68+ ) -> None :
4269 """
4370 Initialize the router.
4471
4572 :param reload_server: Whether to reload the server when the config changes
4673 :param profile_path: Path to the profile file
4774 :param strict: Whether to use strict mode for duplicated tool name.
4875 If True, raise error when duplicated tool name is found else auto resolve by adding server name prefix
76+ :param api_key: Optional API key to use for authentication
77+ :param router_config: Optional router configuration to use instead of the global config
4978 """
5079 self .server_sessions : t .Dict [str , ServerConnection ] = {}
5180 self .capabilities_mapping : t .Dict [str , t .Dict [str , t .Any ]] = defaultdict (dict )
@@ -60,6 +89,26 @@ def __init__(self, reload_server: bool = False, profile_path: str | None = None,
6089 if reload_server :
6190 self .watcher = ConfigWatcher (self .profile_manager .profile_path )
6291 self .strict : bool = strict
92+ self .api_key = api_key
93+ self .router_config = router_config
94+
95+ def create_global_config (self ) -> None :
96+ """
97+ Create a global configuration from the router's configuration.
98+ This is useful if you want to initialize the router with a config
99+ but also want that config to be available globally.
100+ """
101+ if self .api_key is not None :
102+ config_manager = ConfigManager ()
103+ # Save the API key to the global config
104+ config_manager .save_share_config (api_key = self .api_key )
105+
106+ # If router_config is provided, save it to the global config
107+ if self .router_config is not None :
108+ host = self .router_config .get ("host" , DEFAULT_HOST )
109+ port = self .router_config .get ("port" , DEFAULT_PORT )
110+ share_address = self .router_config .get ("share_address" , DEFAULT_SHARE_ADDRESS )
111+ config_manager .save_router_config (host , port , share_address )
63112
64113 def get_unique_servers (self ) -> list [ServerConfig ]:
65114 profiles = self .profile_manager .list_profiles ()
@@ -496,7 +545,8 @@ async def get_sse_server_app(
496545 """
497546 await self .initialize_router ()
498547
499- sse = RouterSseTransport ("/messages/" )
548+ # Pass the API key to the RouterSseTransport
549+ sse = RouterSseTransport ("/messages/" , api_key = self .api_key )
500550
501551 async def handle_sse (request : Request ) -> None :
502552 async with sse .connect_sse (
0 commit comments