Skip to content

Commit 6de3617

Browse files
authored
Merge pull request #44 from HolobiomicsLab/dev
Easier onboarding of Toolomics & Shell MCP multi-client concurrency
2 parents dc2ad94 + 7917fc6 commit 6de3617

5 files changed

Lines changed: 334 additions & 320 deletions

File tree

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,19 @@ In this repository, Toolomics:
3131

3232
## Quick Start
3333

34-
Run Toolomics against a workspace and a port range:
34+
### Deploy all automatically with default setup for Mimosa-AI
35+
36+
The simplest way is to simply run:
37+
38+
```bash
39+
./start.sh
40+
```
41+
42+
This would create a workspace `workspace/` and start all Toolomics MCPs servers enabled using port in the range `5000-5200`.
43+
44+
**Some MCPs server running in docker can take several minutes to start on first run.**
45+
46+
### Deploy all tools automatically with custom port range and workspace
3547

3648
```bash
3749
./start.sh <min port> <max port> <workspace name>

deploy.py

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ def load_config(self) -> Dict[str, dict]:
510510
'enabled': item.get('enabled', True) # Default to enabled
511511
}
512512
else:
513-
raise ValueError(f"Can't parse config file: {self.config_path}")
513+
raise ValueError("Can't parse config.json file")
514514

515515
logger.info(f"Successfully loaded {len(config_dict)} items from config (enabled: {sum(1 for v in config_dict.values() if v.get('enabled'))})")
516516
return config_dict
@@ -588,10 +588,12 @@ def save_config(self, config: Dict[str, dict]) -> None:
588588
def assign_ports(self, server_files: List[Path], compose_files: List[Path] = None,
589589
starting_port: int = HOST_PORT_MIN,
590590
host_port_min: int = HOST_PORT_MIN,
591-
host_port_max: int = HOST_PORT_MAX) -> Dict[str, dict]:
591+
host_port_max: int = HOST_PORT_MAX,
592+
enable_new: bool = False) -> Dict[str, dict]:
592593
"""
593594
Assign ports to server files and docker-compose files with proper range management.
594-
Preserves enabled status for existing servers, new servers are enabled by default.
595+
Preserves enabled status for existing servers, new servers are disabled by default
596+
unless enable_new=True is passed (e.g. via --enable-all flag).
595597
Returns dict mapping path to {"port": int, "enabled": bool}
596598
"""
597599
config = self.load_config()
@@ -618,12 +620,10 @@ def assign_ports(self, server_files: List[Path], compose_files: List[Path] = Non
618620
if next_host_port > host_port_max:
619621
raise RuntimeError(f"No available ports in host range ({host_port_min}-{host_port_max}) for server {server_str}")
620622

621-
config[server_str] = {'port': next_host_port, 'enabled': False}
623+
config[server_str] = {'port': next_host_port, 'enabled': enable_new}
622624
used_ports.add(next_host_port)
623-
logger.info(
624-
f"Assigned host port {next_host_port} to {server_str} "
625-
f"(disabled - edit {self.config_path} to enable)"
626-
)
625+
status = "enabled" if enable_new else "disabled - edit config to enable"
626+
logger.info(f"Assigned host port {next_host_port} to {server_str} ({status})")
627627
next_host_port += 1
628628

629629
# Assign ports to docker-compose files
@@ -639,12 +639,10 @@ def assign_ports(self, server_files: List[Path], compose_files: List[Path] = Non
639639
if next_host_port > host_port_max:
640640
raise RuntimeError(f"No available ports in host range ({host_port_min}-{host_port_max}) for compose {compose_str}")
641641

642-
config[compose_str] = {'port': next_host_port, 'enabled': False}
642+
config[compose_str] = {'port': next_host_port, 'enabled': enable_new}
643643
used_ports.add(next_host_port)
644-
logger.info(
645-
f"Assigned host port {next_host_port} to {compose_str} "
646-
f"(disabled - edit {self.config_path} to enable)"
647-
)
644+
status = "enabled" if enable_new else "disabled - edit config to enable"
645+
logger.info(f"Assigned host port {next_host_port} to {compose_str} ({status})")
648646
next_host_port += 1
649647

650648
self.save_config(config)
@@ -681,7 +679,8 @@ def _signal_handler(self, signum, frame):
681679

682680
def deploy(self, skip_docker: bool = False, starting_port: int = HOST_PORT_MIN,
683681
host_port_min: int = HOST_PORT_MIN,
684-
host_port_max: int = HOST_PORT_MAX):
682+
host_port_max: int = HOST_PORT_MAX,
683+
enable_all: bool = False):
685684
"""Deploy all MCP servers and Docker services"""
686685
if not self.mcp_dir.exists():
687686
raise FileNotFoundError(f"MCP directory {self.mcp_dir} does not exist")
@@ -692,7 +691,7 @@ def deploy(self, skip_docker: bool = False, starting_port: int = HOST_PORT_MIN,
692691

693692
# Assign ports to all services
694693
logger.info("Assigning ports to all services...")
695-
port_config = self.config_manager.assign_ports(server_files, compose_files, starting_port, host_port_min, host_port_max)
694+
port_config = self.config_manager.assign_ports(server_files, compose_files, starting_port, host_port_min, host_port_max, enable_new=enable_all)
696695

697696
# Start Docker services
698697
if not skip_docker:
@@ -757,18 +756,15 @@ def _deploy_docker_services(self, compose_files: List[Path], port_config: Dict[s
757756

758757
# Save config if any ports were reassigned
759758
if config_updated:
760-
logger.info(f"Updating {self.config_manager.config_path} with new port assignments")
759+
logger.info("Updating config.json with new port assignments")
761760
self.config_manager.save_config(port_config)
762761

763762
if started_count > 0:
764763
logger.info(f"Started {started_count} Docker services ({disabled_count} disabled)")
765764
logger.info("Waiting for Docker services to start...")
766765
time.sleep(3)
767766
elif disabled_count > 0:
768-
logger.info(
769-
f"⚠️ All {disabled_count} Docker services are disabled. "
770-
f"Change {self.config_manager.config_path} to enable them."
771-
)
767+
logger.info(f"⚠️ All {disabled_count} Docker services are disabled. Change config.json to enable.")
772768

773769
def _deploy_mcp_servers(self, server_files: List[Path], port_config: Dict[str, dict],
774770
host_port_min: int = HOST_PORT_MIN, host_port_max: int = HOST_PORT_MAX):
@@ -820,15 +816,12 @@ def _deploy_mcp_servers(self, server_files: List[Path], port_config: Dict[str, d
820816

821817
# Save config if any ports were reassigned
822818
if config_updated:
823-
logger.info(f"Updating {self.config_manager.config_path} with new port assignments")
819+
logger.info("Updating config.json with new port assignments")
824820
self.config_manager.save_config(port_config)
825821

826822
logger.info(f"Started {started_count} MCP servers ({disabled_count} disabled)")
827823
if started_count == 0:
828-
raise Exception(
829-
f"⚠️ No MCP server enabled. Change {self.config_manager.config_path} "
830-
"and select MCP servers to enable."
831-
)
824+
raise Exception("⚠️ No MCP server enabled, change config.json and select MCP servers to enable.")
832825

833826
def main():
834827
parser = argparse.ArgumentParser(description="Deploy MCP servers with centralized workspace file management")
@@ -839,6 +832,7 @@ def main():
839832
parser.add_argument("--host_port_min", type=int, default=HOST_PORT_MIN, help="Minimum port for port assignment range.")
840833
parser.add_argument("--host_port_max", type=int, default=HOST_PORT_MAX, help="Maximum port for port assignment range.")
841834
parser.add_argument("--no-docker", action="store_true", help="Skip Docker services")
835+
parser.add_argument("--enable-all", action="store_true", help="Enable all newly discovered MCP servers immediately (skip manual config editing)")
842836
parser.add_argument("--verbose", "-v", action="store_true", help="Enable verbose logging")
843837

844838
args = parser.parse_args()
@@ -856,12 +850,13 @@ def main():
856850
skip_docker=args.no_docker,
857851
starting_port=args.starting_port,
858852
host_port_min=args.host_port_min,
859-
host_port_max=args.host_port_max
853+
host_port_max=args.host_port_max,
854+
enable_all=args.enable_all
860855
)
861856

862857
except Exception as e:
863858
logger.error(f"Deployment failed: {e}")
864859
sys.exit(1)
865860

866861
if __name__ == "__main__":
867-
main()
862+
main()

mcp_host/mcp_search/server.py

Lines changed: 0 additions & 199 deletions
This file was deleted.

0 commit comments

Comments
 (0)