Skip to content

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