Skip to main content
Glama

MY MCP

create_mcp_server•6.62 kB
#!/usr/bin/env python3 import os import shutil import re import sys from pathlib import Path def replace_in_file(file_path, new_name): """Replace all occurrences of my-mcp/my_mcp with new_name in a file.""" try: with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # Replace both underscore and hyphen versions content = content.replace('my_mcp', new_name.replace('-', '_')) content = content.replace('my-mcp', new_name) with open(file_path, 'w', encoding='utf-8') as f: f.write(content) except Exception as e: print(f"Warning: Could not process {file_path}: {e}") def rename_directories(base_path, new_name): """Rename directories from my_mcp to new_name.""" old_dir = base_path / 'my_mcp' new_dir = base_path / new_name.replace('-', '_') if old_dir.exists(): old_dir.rename(new_dir) print(f" Renamed directory: my_mcp -> {new_name.replace('-', '_')}") # Also handle egg-info directory old_egg = base_path / 'my_mcp.egg-info' new_egg = base_path / f"{new_name.replace('-', '_')}.egg-info" if old_egg.exists(): old_egg.rename(new_egg) print(f" Renamed directory: my_mcp.egg-info -> {new_name.replace('-', '_')}.egg-info") def create_mcp_from_template(new_name): """Create a new MCP server from the template.""" script_dir = Path(__file__).parent new_dir = script_dir.parent / new_name # Check if destination already exists if new_dir.exists(): response = input(f"Directory '{new_name}' already exists. Overwrite? (y/n): ") if response.lower() != 'y': print("Aborted.") return False shutil.rmtree(new_dir) print(f"\nCreating new MCP server '{new_name}'...") # Copy the entire project, excluding unnecessary files and directories def ignore_patterns(dir, files): ignore = [] ignore_dirs = {'.git', '__pycache__', '.venv', 'venv', 'cache', '.claude', '.pytest_cache', '.coverage', 'htmlcov', '.env', 'secrets', '*.egg-info', 'dist', 'build', '.DS_Store', 'uv.lock'} for f in files: # Check if file/dir should be ignored if f in ignore_dirs or f == 'create_mcp_server': ignore.append(f) # Also check for egg-info directories with any prefix elif f.endswith('.egg-info'): ignore.append(f) # Ignore hidden files and directories (except .gitignore which might be useful) elif f.startswith('.') and f != '.gitignore': ignore.append(f) return ignore print(" Copying template files...") shutil.copytree(script_dir, new_dir, ignore=ignore_patterns) print(f" Copied template to {new_dir}") print(" Excluded: .venv, cache, .claude, __pycache__, .env, uv.lock, and other temporary/build files") # Files that need text replacement files_to_process = [ 'docs/README.md', # Process this before copying to root 'pyproject.toml', 'setup.py', 'docker-compose.yml', 'build-docker-image.sh', 'Makefile', 'Dockerfile', 'config.json', 'docs/build-options.md', 'docs/docker-usage.md', ] # Process main files print("\nReplacing 'my_mcp' and 'my-mcp' references...") for file_path in files_to_process: full_path = new_dir / file_path if full_path.exists(): replace_in_file(full_path, new_name) print(f" Processed: {file_path}") # Process Python files in the module directory module_dir = new_dir / 'my_mcp' if module_dir.exists(): for py_file in module_dir.rglob('*.py'): relative_path = py_file.relative_to(new_dir) replace_in_file(py_file, new_name) print(f" Processed: {relative_path}") # Process test files test_dir = new_dir / 'tests' if test_dir.exists(): for py_file in test_dir.rglob('*.py'): relative_path = py_file.relative_to(new_dir) replace_in_file(py_file, new_name) print(f" Processed: {relative_path}") # Rename directories print("\nRenaming directories...") rename_directories(new_dir, new_name) # Copy the proper README from docs to root print("\nSetting up documentation...") docs_readme = new_dir / 'docs' / 'README.md' root_readme = new_dir / 'README.md' if docs_readme.exists(): # Remove the template-specific README first if root_readme.exists(): root_readme.unlink() # Copy the proper project README shutil.copy2(docs_readme, root_readme) print(f" Copied docs/README.md to project root") # Optionally remove docs/README.md to avoid duplication # docs_readme.unlink() # print(f" Removed docs/README.md (now in root)") print(f"\nāœ… Successfully created new MCP server: {new_name}") print(f"šŸ“ Location: {new_dir}") print("\nNext steps:") print(f" 1. cd ../{new_name}") print(" 2. Review and customize the README.md") print(" 3. Implement your MCP tools in the server.py file") print(" 4. Run 'uv sync' to install dependencies and create uv.lock") print(" 5. Update config.json with your server details") return True def validate_name(name): """Validate the MCP name.""" # Check for valid Python package name (with hyphens allowed) if not re.match(r'^[a-z][a-z0-9-]*$', name): print("Error: Name must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.") return False if name == 'my-mcp' or name == 'my_mcp': print("Error: Please choose a different name than 'my-mcp' or 'my_mcp'.") return False return True def main(): print("MCP Server Creator") print("=" * 40) print("This script will create a new MCP server from this template.\n") # Get the new MCP name while True: new_name = input("Enter the name for your new MCP server (e.g., weather-mcp): ").strip() if not new_name: print("Error: Name cannot be empty.\n") continue if validate_name(new_name): break print() # Create the new MCP server if create_mcp_from_template(new_name): sys.exit(0) else: sys.exit(1) if __name__ == "__main__": main()

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/vaheandonians/my-mcp'

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