Skip to main content
Glama
by OxSci-AI
setup.py8.33 kB
#!/usr/bin/env python3 """ MCP Server Setup Script This script sets up a new MCP server by: 1. Prompting for service name and tool name 2. Creating the project directory structure 3. Configuring pyproject.toml with the service name 4. Creating tool file from template 5. Updating __init__.py to import the tool 6. Initializing git repository """ import os import re import shutil import sys from pathlib import Path def get_input(prompt: str, validator=None) -> str: """Get user input with optional validation.""" while True: value = input(prompt).strip() if not value: print(" Error: Input cannot be empty. Please try again.") continue if validator and not validator(value): continue return value def validate_service_name(name: str) -> bool: """Validate service name format.""" # Allow alphanumeric and hyphens, must start with letter if not re.match(r"^[a-z][a-z0-9-]*$", name): print( " Error: Service name must start with a letter and contain only lowercase letters, numbers, and hyphens." ) return False return True def validate_tool_name(name: str) -> bool: """Validate tool name format.""" # Allow alphanumeric and underscores, must start with letter if not re.match(r"^[a-z][a-z0-9_]*$", name): print( " Error: Tool name must start with a letter and contain only lowercase letters, numbers, and underscores." ) return False return True def to_pascal_case(name: str) -> str: """Convert snake_case or kebab-case to PascalCase.""" parts = re.split(r"[_-]", name) return "".join(word.capitalize() for word in parts) def setup_service(): """Main setup function.""" print("=" * 70) print("MCP Server Setup") print("=" * 70) print() # Get service name print("Step 1: Service Configuration") print("-" * 70) service_name = get_input( "Enter service name (e.g., 'document-processor'): ", validate_service_name ) folder_name = f"mcp-{service_name}" description = f"MCP {service_name.replace('-', ' ').title()} Server" print(f"\n → Service folder: {folder_name}") print(f" → Description: {description}") print() # Get tool name print("Step 2: Tool Configuration") print("-" * 70) tool_name = get_input( "Enter tool name (e.g., 'document_processor'): ", validate_tool_name ) tool_file = f"{tool_name}.py" print(f"\n → Tool file: app/tools/{tool_file}") print() # Confirm setup print("Step 3: Confirmation") print("-" * 70) print(f"Service Name: {folder_name}") print(f"Description: {description}") print(f"Tool Name: {tool_name}") print() confirm = input("Proceed with setup? (y/n): ").strip().lower() if confirm != "y": print("\nSetup cancelled.") return print() print("Step 4: Creating Project") print("-" * 70) # Get script directory (scaffold template location) script_dir = Path(__file__).parent target_dir = Path.cwd() / folder_name # Check if target directory already exists if target_dir.exists(): print(f"\n❌ Error: Directory '{folder_name}' already exists!") return try: # Create target directory print(f"Creating directory: {folder_name}") target_dir.mkdir(parents=True, exist_ok=True) # Copy all files and directories except setup.py, install.py, and tool_template.py print("Copying template files...") for item in script_dir.iterdir(): if item.name in [ "setup.py", "install.py", ".git", "__pycache__", ".DS_Store", ]: continue dest = target_dir / item.name if item.is_file(): shutil.copy2(item, dest) elif item.is_dir(): shutil.copytree(item, dest) # Update pyproject.toml print("Configuring pyproject.toml...") pyproject_path = target_dir / "pyproject.toml" content = pyproject_path.read_text() content = content.replace( 'name = "mcp-server-template"', f'name = "{folder_name}"' ) content = content.replace( 'description = "MCP Server Template built with oxsci-oma-mcp"', f'description = "{description}"', ) pyproject_path.write_text(content) # Create tool file from template print(f"Creating tool file: app/tools/{tool_file}") tool_template_path = target_dir / "app" / "tools" / "tool_template.py" tool_path = target_dir / "app" / "tools" / tool_file # Check if template exists, otherwise use example_tool.py as template if not tool_template_path.exists(): tool_template_path = target_dir / "app" / "tools" / "example_tool.py" tool_content = tool_template_path.read_text() # Replace template placeholders tool_content = tool_content.replace("example_tool", tool_name) tool_content = tool_content.replace("ExampleTool", to_pascal_case(tool_name)) tool_content = tool_content.replace( "Example tool that processes text input", f"{to_pascal_case(tool_name)} tool", ) tool_path.write_text(tool_content) # Remove template file if it exists if tool_template_path.name == "tool_template.py": tool_template_path.unlink() # Remove example_tool.py if we created a different tool elif tool_name != "example_tool": example_tool = target_dir / "app" / "tools" / "example_tool.py" if example_tool.exists(): example_tool.unlink() # Update __init__.py for tools tools_init = target_dir / "app" / "tools" / "__init__.py" init_content = f'''""" MCP Tools Package Import all your tool modules here to ensure they are registered with @oma_tool. """ # Import your tools here from . import {tool_name} # noqa: F401 ''' tools_init.write_text(init_content) # Initialize git repository print("Initializing git repository...") os.chdir(target_dir) os.system("git init") os.system("git add .") os.system( f'git commit -m "Initial commit: {folder_name} from oxsci-mcp-scaffold"' ) # Create .gitignore if not exists gitignore_path = target_dir / ".gitignore" if not gitignore_path.exists(): gitignore_content = """# Python __pycache__/ *.py[cod] *$py.class *.so .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # Virtual environments venv/ env/ ENV/ .venv/ # Poetry poetry.lock # IDEs .vscode/ .idea/ *.swp *.swo *~ # Testing .pytest_cache/ .coverage htmlcov/ # OS .DS_Store Thumbs.db # Environment .env .env.local """ gitignore_path.write_text(gitignore_content) os.system("git add .gitignore") os.system('git commit -m "Add .gitignore"') print() print("=" * 70) print("✅ Setup Complete!") print("=" * 70) print() print(f"Your MCP server has been created in: {folder_name}") print() print("Next steps:") print() print(f" 1. cd {folder_name}") print(f" 2. ./entrypoint-dev.sh # Configure AWS CodeArtifact") print(f" 3. poetry install # Install dependencies") print(f" 4. Edit app/tools/{tool_file} # Implement your tool logic") print(f" 5. poetry run uvicorn app.core.main:app --reload --port 8060") print() print("For more information, see README.md") print() except Exception as e: print(f"\n❌ Error during setup: {e}") import traceback traceback.print_exc() if target_dir.exists(): print(f"\nCleaning up {folder_name}...") shutil.rmtree(target_dir) return if __name__ == "__main__": try: setup_service() except KeyboardInterrupt: print("\n\nSetup cancelled by user.") sys.exit(1)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OxSci-AI/oxsci-mcp-scaffold'

If you have feedback or need assistance with the MCP directory API, please join our Discord server