signalwire.mcp_gateway¶
signalwire.mcp_gateway
¶
Copyright (c) 2025 SignalWire
This file is part of the SignalWire SDK.
Licensed under the MIT License. See LICENSE file in the project root for full license information.
MCP-SWAIG Gateway Package
HTTP/HTTPS server that bridges MCP servers with SignalWire SWAIG functions.
__all__ = ['MCPClient', 'MCPGateway', 'MCPManager', 'MCPService', 'Session', 'SessionManager', 'main']
module-attribute
¶
MCPGateway
¶
Main gateway service class
config_loader = ConfigLoader([config_path])
instance-attribute
¶
config = self.config_loader.substitute_vars(self.config_loader.get_config())
instance-attribute
¶
security = SecurityConfig(config_file=config_path, service_name='mcp')
instance-attribute
¶
app = Flask(__name__)
instance-attribute
¶
mcp_manager = MCPManager(self.config)
instance-attribute
¶
session_manager = SessionManager(self.config)
instance-attribute
¶
server = None
instance-attribute
¶
rate_config = self.config.get('rate_limiting', {})
instance-attribute
¶
limiter = Limiter(app=(self.app), key_func=get_remote_address, default_limits=default_limits, storage_uri=storage_uri)
instance-attribute
¶
__init__(config_path='config.json')
¶
run()
¶
Run the gateway service
shutdown()
¶
Shutdown the gateway service
Session
dataclass
¶
Represents an active MCP session
session_id
instance-attribute
¶
service_name
instance-attribute
¶
process
instance-attribute
¶
created_at = field(default_factory=(datetime.now))
class-attribute
instance-attribute
¶
last_accessed = field(default_factory=(datetime.now))
class-attribute
instance-attribute
¶
timeout = 300
class-attribute
instance-attribute
¶
metadata = field(default_factory=dict)
class-attribute
instance-attribute
¶
is_expired
property
¶
Check if session has expired based on timeout
is_alive
property
¶
Check if the underlying MCP client is still running
touch()
¶
Update last accessed time
__init__(session_id, service_name, process, created_at=datetime.now(), last_accessed=datetime.now(), timeout=300, metadata=dict())
¶
SessionManager
¶
Manages MCP server sessions with automatic cleanup
config = config
instance-attribute
¶
sessions = {}
instance-attribute
¶
lock = threading.RLock()
instance-attribute
¶
cleanup_interval = config.get('session', {}).get('cleanup_interval', 60)
instance-attribute
¶
max_sessions_per_service = config.get('session', {}).get('max_sessions_per_service', 100)
instance-attribute
¶
max_total_sessions = config.get('session', {}).get('max_total_sessions', max_total_sessions)
instance-attribute
¶
default_timeout = config.get('session', {}).get('default_timeout', 300)
instance-attribute
¶
cleanup_thread = threading.Thread(target=(self._cleanup_loop), daemon=True)
instance-attribute
¶
__init__(config, max_total_sessions=500)
¶
create_session(session_id, service_name, process, timeout=None, metadata=None)
¶
Create and register a new session
get_session(session_id)
¶
Get an active session by ID
close_session(session_id)
¶
Close and remove a session
list_sessions()
¶
List all active sessions with their info
get_service_session_count(service_name)
¶
Get number of active sessions for a service
shutdown()
¶
Shutdown all sessions and cleanup
MCPService
dataclass
¶
Configuration for an MCP service
name
instance-attribute
¶
command
instance-attribute
¶
description
instance-attribute
¶
enabled = True
class-attribute
instance-attribute
¶
sandbox_config = None
class-attribute
instance-attribute
¶
__post_init__()
¶
__hash__()
¶
__init__(name, command, description, enabled=True, sandbox_config=None)
¶
MCPClient
¶
Client for communicating with a single MCP server process
service = service
instance-attribute
¶
process = None
instance-attribute
¶
request_id = 0
instance-attribute
¶
pending_requests = {}
instance-attribute
¶
response_queue = queue.Queue()
instance-attribute
¶
reader_thread = None
instance-attribute
¶
lock = threading.Lock()
instance-attribute
¶
tools = []
instance-attribute
¶
sandbox_base_dir = sandbox_base_dir
instance-attribute
¶
sandbox_dir = None
instance-attribute
¶
__init__(service, sandbox_base_dir='./sandbox')
¶
start()
¶
Start the MCP server process and initialize connection
stop()
¶
Stop the MCP server process and clean up sandbox
call_tool(tool_name, arguments)
¶
Call a tool on the MCP server
call_method(method, params)
¶
Call an RPC method and wait for response
get_tools()
¶
Get the list of available tools
MCPManager
¶
Manages multiple MCP services and their lifecycles
config = config
instance-attribute
¶
services = {}
instance-attribute
¶
clients = {}
instance-attribute
¶
sandbox_base_dir = config.get('session', {}).get('sandbox_dir', './sandbox')
instance-attribute
¶
__init__(config)
¶
get_service(service_name)
¶
Get a service definition by name
list_services()
¶
List all available services
create_client(service_name)
¶
Create a new MCP client for a service
get_service_tools(service_name)
¶
Get tools for a service by starting a temporary instance
validate_services()
¶
Validate that all services can be started
shutdown()
¶
Shutdown all active MCP clients
main()
¶
Main entry point
gateway_service
¶
Copyright (c) 2025 SignalWire
This file is part of the SignalWire SDK.
Licensed under the MIT License. See LICENSE file in the project root for full license information.
MCP-SWAIG Gateway Service
HTTP/HTTPS server that bridges MCP servers with SignalWire SWAIG functions. Manages sessions, handles authentication, and translates between protocols.
logger = logging.getLogger('gateway_service')
module-attribute
¶
MCPGateway
¶
Main gateway service class
config_loader = ConfigLoader([config_path])
instance-attribute
¶
config = self.config_loader.substitute_vars(self.config_loader.get_config())
instance-attribute
¶
security = SecurityConfig(config_file=config_path, service_name='mcp')
instance-attribute
¶
app = Flask(__name__)
instance-attribute
¶
mcp_manager = MCPManager(self.config)
instance-attribute
¶
session_manager = SessionManager(self.config)
instance-attribute
¶
server = None
instance-attribute
¶
rate_config = self.config.get('rate_limiting', {})
instance-attribute
¶
limiter = Limiter(app=(self.app), key_func=get_remote_address, default_limits=default_limits, storage_uri=storage_uri)
instance-attribute
¶
__init__(config_path='config.json')
¶
run()
¶
Run the gateway service
shutdown()
¶
Shutdown the gateway service
main()
¶
Main entry point
mcp_manager
¶
Copyright (c) 2025 SignalWire
This file is part of the SignalWire SDK.
Licensed under the MIT License. See LICENSE file in the project root for full license information.
MCP Server Manager for MCP Gateway
Handles spawning, communication, and management of MCP server processes. Implements the MCP protocol client functionality.
logger = logging.getLogger(__name__)
module-attribute
¶
MCPService
dataclass
¶
Configuration for an MCP service
name
instance-attribute
¶
command
instance-attribute
¶
description
instance-attribute
¶
enabled = True
class-attribute
instance-attribute
¶
sandbox_config = None
class-attribute
instance-attribute
¶
__init__(name, command, description, enabled=True, sandbox_config=None)
¶
__post_init__()
¶
__hash__()
¶
MCPClient
¶
Client for communicating with a single MCP server process
service = service
instance-attribute
¶
process = None
instance-attribute
¶
request_id = 0
instance-attribute
¶
pending_requests = {}
instance-attribute
¶
response_queue = queue.Queue()
instance-attribute
¶
reader_thread = None
instance-attribute
¶
lock = threading.Lock()
instance-attribute
¶
tools = []
instance-attribute
¶
sandbox_base_dir = sandbox_base_dir
instance-attribute
¶
sandbox_dir = None
instance-attribute
¶
__init__(service, sandbox_base_dir='./sandbox')
¶
start()
¶
Start the MCP server process and initialize connection
stop()
¶
Stop the MCP server process and clean up sandbox
call_tool(tool_name, arguments)
¶
Call a tool on the MCP server
call_method(method, params)
¶
Call an RPC method and wait for response
get_tools()
¶
Get the list of available tools
MCPManager
¶
Manages multiple MCP services and their lifecycles
config = config
instance-attribute
¶
services = {}
instance-attribute
¶
clients = {}
instance-attribute
¶
sandbox_base_dir = config.get('session', {}).get('sandbox_dir', './sandbox')
instance-attribute
¶
__init__(config)
¶
get_service(service_name)
¶
Get a service definition by name
list_services()
¶
List all available services
create_client(service_name)
¶
Create a new MCP client for a service
get_service_tools(service_name)
¶
Get tools for a service by starting a temporary instance
validate_services()
¶
Validate that all services can be started
shutdown()
¶
Shutdown all active MCP clients
session_manager
¶
Copyright (c) 2025 SignalWire
This file is part of the SignalWire SDK.
Licensed under the MIT License. See LICENSE file in the project root for full license information.
Session Manager for MCP Gateway
Manages lifecycle of MCP server sessions tied to SignalWire call IDs. Handles timeouts, cleanup, and resource limits.
logger = logging.getLogger(__name__)
module-attribute
¶
Session
dataclass
¶
Represents an active MCP session
session_id
instance-attribute
¶
service_name
instance-attribute
¶
process
instance-attribute
¶
created_at = field(default_factory=(datetime.now))
class-attribute
instance-attribute
¶
last_accessed = field(default_factory=(datetime.now))
class-attribute
instance-attribute
¶
timeout = 300
class-attribute
instance-attribute
¶
metadata = field(default_factory=dict)
class-attribute
instance-attribute
¶
is_expired
property
¶
Check if session has expired based on timeout
is_alive
property
¶
Check if the underlying MCP client is still running
__init__(session_id, service_name, process, created_at=datetime.now(), last_accessed=datetime.now(), timeout=300, metadata=dict())
¶
touch()
¶
Update last accessed time
SessionManager
¶
Manages MCP server sessions with automatic cleanup
config = config
instance-attribute
¶
sessions = {}
instance-attribute
¶
lock = threading.RLock()
instance-attribute
¶
cleanup_interval = config.get('session', {}).get('cleanup_interval', 60)
instance-attribute
¶
max_sessions_per_service = config.get('session', {}).get('max_sessions_per_service', 100)
instance-attribute
¶
max_total_sessions = config.get('session', {}).get('max_total_sessions', max_total_sessions)
instance-attribute
¶
default_timeout = config.get('session', {}).get('default_timeout', 300)
instance-attribute
¶
cleanup_thread = threading.Thread(target=(self._cleanup_loop), daemon=True)
instance-attribute
¶
__init__(config, max_total_sessions=500)
¶
create_session(session_id, service_name, process, timeout=None, metadata=None)
¶
Create and register a new session
get_session(session_id)
¶
Get an active session by ID
close_session(session_id)
¶
Close and remove a session
list_sessions()
¶
List all active sessions with their info
get_service_session_count(service_name)
¶
Get number of active sessions for a service
shutdown()
¶
Shutdown all sessions and cleanup