Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions multi_ssh_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import paramiko
from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import StaticTokenVerifier
import jc

# Import security utilities
Expand Down Expand Up @@ -424,8 +425,23 @@ def main():
logger.info(f"Loaded {len(ssh_manager.servers_config)} server(s): {', '.join(ssh_manager.servers_config.keys())}")

# Create FastMCP server
mcp = FastMCP("Multi-SSH Server")
bearer_token = os.environ.get("MCP_TOKEN")

if bearer_token:
verifier = StaticTokenVerifier(
tokens={
bearer_token: {
"client_id": "superuser",
"scopes": ["read:data", "write:data", "admin:users"]
}
},
required_scopes=["read:data"]
)

mcp = FastMCP("Multi-SSH Server", auth=verifier)
else:
mcp = FastMCP("Multi-SSH Server")

@mcp.tool()
def list_servers() -> str:
"""List all configured SSH servers with their details"""
Expand Down Expand Up @@ -752,24 +768,35 @@ def network_diagnostics(command_type: str, destination: str, server_name: str =
return f"{command_type} failed: {result['error']}"

# Run the FastMCP server with transport selection
transport = os.environ.get("MCP_TRANSPORT", "stdio")
transport = os.environ.get("MCP_TRANSPORT", "stdio").lower()

if transport == "sse":
# Server-Sent Events mode for HTTP streaming
# Server-Sent Events mode for HTTP streaming (not recommended)
import uvicorn
from fastmcp.sse import create_sse_transport
sse_transport = mcp.sse_app()

port = int(os.environ.get("MCP_PORT", "8080"))
host = os.environ.get("MCP_HOST", "0.0.0.0")

logger.info(f"Starting SSE transport on {host}:{port}")
sse_transport = create_sse_transport(mcp, host=host, port=port)
uvicorn.run(sse_transport, host=host, port=port, log_level="info")

elif transport == "http":
# Streamable HTTP transport (recommended)
import uvicorn
http_transport = mcp.http_app()

port = int(os.environ.get("MCP_PORT", "8080"))
host = os.environ.get("MCP_HOST", "0.0.0.0")

logger.info(f"Starting Streamable HTTP transport on {host}:{port}")
uvicorn.run(http_transport, host=host, port=port, log_level="info")

else:
# Default stdio transport
logger.info("Starting stdio transport")
mcp.run()


if __name__ == "__main__":
main()
main()