Skip to main content
Glama

DevDb MCP Server

boot.sh23.5 kB
#!/bin/bash set -e # Cleanup function to run on exit cleanup() { if [[ -d "$TODO_APP_DIR" ]]; then print_info "Cleaning up ephemeral Django application..." cd "$TODO_APP_DIR" # Remove everything except .gitignore find . -mindepth 1 -not -name '.gitignore' -exec rm -rf {} + 2>/dev/null || true print_success "Cleanup completed. Only .gitignore remains." fi } # Set trap to run cleanup on script exit trap cleanup EXIT # Default database type DB_TYPE="${1:-sqlite}" # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Validate database type if [[ ! "$DB_TYPE" =~ ^(mysql|postgres|sqlite)$ ]]; then print_error "Invalid database type: $DB_TYPE" print_info "Supported types: mysql, postgres, sqlite" exit 1 fi print_info "Setting up Django application with $DB_TYPE database..." # Get script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TODO_APP_DIR="$SCRIPT_DIR/todo-app" # Check if database containers are running (skip for SQLite) if [[ "$DB_TYPE" != "sqlite" ]]; then case "$DB_TYPE" in "mysql") if ! docker ps --format "table {{.Names}}" | grep -q "mysql-devdb-triage"; then print_info "MySQL database container 'mysql-devdb-triage' is not running. Starting it now..." docker run -d --name mysql-devdb-triage -p 2222:3306 -e MYSQL_ROOT_PASSWORD=mysecretpassword -e MYSQL_DATABASE=sample_db mysql:8.0 # Wait for MySQL to start up sleep 10 fi print_success "MySQL database container is running" ;; "postgres") if ! docker ps --format "table {{.Names}}" | grep -q "postgres-devdb-triage"; then print_info "PostgreSQL database container 'postgres-devdb-triage' is not running. Starting it now..." docker run -d --name postgres-devdb-triage -p 3333:5432 -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_DB=sample_db postgres:16 # Wait for PostgreSQL to start up sleep 5 fi print_success "PostgreSQL database container is running" ;; esac fi # Check if Django and Python are available if ! command -v django-admin &> /dev/null; then print_error "Django is not installed. Please install Django first:" print_info " pip install django" exit 1 fi if ! command -v python3 &> /dev/null; then print_error "Python3 is not installed. Please install Python3 first." exit 1 fi # Clear the todo-app directory print_info "Clearing existing Django application..." rm -rf "$TODO_APP_DIR" mkdir -p "$TODO_APP_DIR" # Create a new Django project in todo-app directory print_info "Creating a new Django project in todo-app..." cd "$(dirname "$TODO_APP_DIR")" django-admin startproject todoapp "$(basename "$TODO_APP_DIR")" # Change to the todo-app directory cd "$TODO_APP_DIR" # Remove git-related files and setup gitignore for ephemeral application print_info "Configuring gitignore for ephemeral app..." # Overwrite .gitignore to ignore everything except itself cat > .gitignore << 'EOF' # Ignore everything in this ephemeral Django application directory * # But don't ignore this .gitignore file itself !.gitignore EOF # Create and activate virtual environment print_info "Creating virtual environment..." python3 -m venv venv source venv/bin/activate # Install Django and required database packages print_info "Installing required packages..." pip install django==4.2.10 case "$DB_TYPE" in "mysql") # Use PyMySQL instead of mysqlclient (pure Python implementation) pip install pymysql ;; "postgres") pip install psycopg2-binary ;; "sqlite") # SQLite support is built into Python ;; esac # Create todos app first print_info "Creating todos Django app..." python3 manage.py startapp todos # Update database configuration print_info "Configuring database connection..." case "$DB_TYPE" in "mysql") cat > todoapp/settings.py << 'EOF' import os from pathlib import Path # Initialize PyMySQL to be used as MySQLdb import pymysql pymysql.install_as_MySQLdb() BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = 'django-insecure-ephemeral-key-for-demo-only' DEBUG = True ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todos', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'todoapp.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'todoapp.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'sample_db', 'USER': 'root', 'PASSWORD': 'mysecretpassword', 'HOST': '127.0.0.1', 'PORT': '2222', 'OPTIONS': { 'charset': 'utf8mb4', }, } } LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_TZ = True STATIC_URL = 'static/' STATICFILES_DIRS = [BASE_DIR / 'static'] DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' EOF ;; "postgres") cat > todoapp/settings.py << 'EOF' import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = 'django-insecure-ephemeral-key-for-demo-only' DEBUG = True ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todos', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'todoapp.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'todoapp.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'sample_db', 'USER': 'postgres', 'PASSWORD': 'mysecretpassword', 'HOST': '127.0.0.1', 'PORT': '3333', } } LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_TZ = True STATIC_URL = 'static/' STATICFILES_DIRS = [BASE_DIR / 'static'] DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' EOF ;; "sqlite") cat > todoapp/settings.py << 'EOF' import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = 'django-insecure-ephemeral-key-for-demo-only' DEBUG = True ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todos', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'todoapp.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'todoapp.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_TZ = True STATIC_URL = 'static/' STATICFILES_DIRS = [BASE_DIR / 'static'] DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' EOF ;; esac # Create todos models print_info "Creating models..." cat > todos/models.py << 'EOF' import uuid from django.db import models class Category(models.Model): id = models.CharField(max_length=36, primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=255) description = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Product(models.Model): id = models.CharField(max_length=36, primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=255) description = models.TextField(blank=True) price = models.DecimalField(max_digits=10, decimal_places=2) stock_quantity = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.name class User(models.Model): id = models.CharField(max_length=36, primary_key=True, default=uuid.uuid4, editable=False) email = models.EmailField(unique=True) name = models.CharField(max_length=255) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Todo(models.Model): id = models.CharField(max_length=36, primary_key=True, default=uuid.uuid4, editable=False) title = models.CharField(max_length=255) completed = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.title class Meta: ordering = ['-created_at'] EOF # Create todos views print_info "Creating views..." cat > todos/views.py << 'EOF' from django.shortcuts import render, redirect, get_object_or_404 from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods from .models import Todo, Product, User, Category import json def home(request): products = Product.objects.all()[:10] users = User.objects.all()[:5] categories = Category.objects.all() context = { 'products': products, 'users': users, 'categories': categories, } return render(request, 'home.html', context) def todo_list(request): todos = Todo.objects.all() return render(request, 'todos.html', {'todos': todos}) @csrf_exempt @require_http_methods(["POST"]) def add_todo(request): title = request.POST.get('title', '').strip() if title: Todo.objects.create(title=title) return redirect('todo_list') @csrf_exempt @require_http_methods(["POST"]) def toggle_todo(request, todo_id): todo = get_object_or_404(Todo, id=todo_id) todo.completed = not todo.completed todo.save() return redirect('todo_list') @csrf_exempt @require_http_methods(["POST"]) def delete_todo(request, todo_id): todo = get_object_or_404(Todo, id=todo_id) todo.delete() return redirect('todo_list') EOF # Create URL patterns print_info "Creating URL patterns..." cat > todos/urls.py << 'EOF' from django.urls import path from . import views urlpatterns = [ path('', views.home, name='home'), path('todos/', views.todo_list, name='todo_list'), path('todos/add/', views.add_todo, name='add_todo'), path('todos/<str:todo_id>/toggle/', views.toggle_todo, name='toggle_todo'), path('todos/<str:todo_id>/delete/', views.delete_todo, name='delete_todo'), ] EOF # Update main URLs cat > todoapp/urls.py << 'EOF' from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('todos.urls')), ] EOF # Create templates directory and templates print_info "Creating templates..." mkdir -p templates mkdir -p static # Create a capitalized version of DB_TYPE DB_TYPE_CAPITALIZED=$(echo "${DB_TYPE}" | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}') cat > templates/base.html << EOF <!DOCTYPE html> <html> <head> <title>Django ${DB_TYPE_CAPITALIZED} Demo</title> <meta name="viewport" content="width=device-width,initial-scale=1"> </head> <body> {% block content %} {% endblock %} </body> </html> EOF cat > templates/home.html << EOF {% extends 'base.html' %} {% block content %} <div style="font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px;"> <h1 style="color: #333; text-align: center;">Django ${DB_TYPE_CAPITALIZED} Demo Application</h1> <div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px;"> <h2 style="color: #28a745;">🎉 Success! Django is connected to ${DB_TYPE_CAPITALIZED}</h2> <p>This application is running Django with a ${DB_TYPE_CAPITALIZED} database backend.</p> EOF case "$DB_TYPE" in "mysql") cat >> templates/home.html << 'EOF' <p><strong>Database:</strong> MySQL via Docker container</p> <p><strong>Connection:</strong> 127.0.0.1:2222</p> EOF ;; "postgres") cat >> templates/home.html << 'EOF' <p><strong>Database:</strong> PostgreSQL via Docker container</p> <p><strong>Connection:</strong> 127.0.0.1:3333</p> EOF ;; "sqlite") cat >> templates/home.html << 'EOF' <p><strong>Database:</strong> SQLite (file-based)</p> <p><strong>File:</strong> db.sqlite3</p> EOF ;; esac cat >> templates/home.html << 'EOF' <p style="margin-top: 15px;"><a href="/todos/" style="background: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px;">📝 Try the Todo App</a></p> </div> <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px;"> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="color: #007bff; margin-top: 0;">📦 Products ({{ products|length }})</h3> {% for product in products %} <div style="border-bottom: 1px solid #eee; padding: 10px 0;"> <strong>{{ product.name }}</strong><br> <small style="color: #666;">{{ product.description }}</small><br> <span style="color: #28a745; font-weight: bold;">${{ product.price }}</span> </div> {% endfor %} </div> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="color: #28a745; margin-top: 0;">👥 Users ({{ users|length }})</h3> {% for user in users %} <div style="border-bottom: 1px solid #eee; padding: 10px 0;"> <strong>{{ user.name }}</strong><br> <small style="color: #666;">{{ user.email }}</small> </div> {% endfor %} </div> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="color: #ffc107; margin-top: 0;">🏷️ Categories ({{ categories|length }})</h3> {% for category in categories %} <div style="border-bottom: 1px solid #eee; padding: 10px 0;"> <strong>{{ category.name }}</strong><br> <small style="color: #666;">{{ category.description }}</small> </div> {% endfor %} </div> </div> </div> {% endblock %} EOF cat > templates/todos.html << EOF {% extends 'base.html' %} {% block content %} <div style="font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px;"> <h1 style="color: #333; text-align: center;">📝 Todo App - ${DB_TYPE_CAPITALIZED} Backend</h1> <div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px;"> <h3>Add New Todo</h3> <form action="/todos/add/" method="post" style="display: flex; gap: 10px;"> <input type="text" name="title" placeholder="Enter todo item..." style="flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px;" required> <button type="submit" style="background: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer;">Add Todo</button> </form> </div> <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <h3 style="margin-top: 0;">Your Todos ({{ todos|length }})</h3> {% if not todos %} <p style="color: #666; text-align: center; padding: 40px;">No todos yet. Add one above to get started!</p> {% else %} {% for todo in todos %} <div style="display: flex; align-items: center; justify-content: space-between; padding: 15px; border-bottom: 1px solid #eee; {% if todo.completed %}background: #f8f9fa;{% endif %}"> <div style="flex: 1;"> <span style="{% if todo.completed %}text-decoration: line-through; color: #666;{% endif %}"> {{ todo.title }} </span> {% if todo.completed %} <span style="color: #28a745; font-size: 12px; margin-left: 10px;">✓ Completed</span> {% endif %} </div> <div style="display: flex; gap: 10px;"> <form action="/todos/{{ todo.id }}/toggle/" method="post" style="display: inline;"> <button type="submit" style="background: {% if todo.completed %}#ffc107{% else %}#28a745{% endif %}; color: white; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;"> {% if todo.completed %}Undo{% else %}Done{% endif %} </button> </form> <form action="/todos/{{ todo.id }}/delete/" method="post" style="display: inline;"> <button type="submit" style="background: #dc3545; color: white; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px;" onclick="return confirm('Are you sure you want to delete this todo?')"> Delete </button> </form> </div> </div> {% endfor %} {% endif %} </div> <div style="text-align: center; margin-top: 30px;"> <a href="/" style="color: #007bff; text-decoration: none;">← Back to Home</a> </div> </div> {% endblock %} EOF # Create database setup script print_info "Creating database setup script..." cat > setup_database.py << 'EOF' import os import sys import django from django.conf import settings # Setup Django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'todoapp.settings') django.setup() from django.db import connection from todos.models import Category, Product, User, Todo import uuid def setup_database(): print("Setting up database and sample data...") # Create tables from django.core.management import execute_from_command_line execute_from_command_line(['manage.py', 'makemigrations', 'todos']) execute_from_command_line(['manage.py', 'migrate']) # Clear existing data Todo.objects.all().delete() Product.objects.all().delete() User.objects.all().delete() Category.objects.all().delete() # Create sample categories categories_data = [ {'name': 'Electronics', 'description': 'Electronic devices and gadgets'}, {'name': 'Clothing', 'description': 'Apparel and fashion items'}, {'name': 'Books', 'description': 'Books and publications'} ] for cat_data in categories_data: Category.objects.create(**cat_data) # Create sample products products_data = [ {'name': 'Smartphone X', 'description': 'Latest smartphone with advanced features', 'price': 899.99, 'stock_quantity': 50}, {'name': 'Laptop Pro', 'description': 'High-performance laptop for professionals', 'price': 1299.99, 'stock_quantity': 25}, {'name': 'Cotton T-shirt', 'description': 'Comfortable cotton t-shirt', 'price': 19.99, 'stock_quantity': 200} ] for prod_data in products_data: Product.objects.create(**prod_data) # Create sample users users_data = [ {'email': 'john.doe@example.com', 'name': 'John Doe'}, {'email': 'jane.smith@example.com', 'name': 'Jane Smith'} ] for user_data in users_data: User.objects.create(**user_data) print("Database setup completed successfully!") if __name__ == '__main__': setup_database() EOF # Setup database and sample data print_info "Setting up database and sample data..." # For MySQL and PostgreSQL, wait a bit longer to ensure the database is fully ready if [[ "$DB_TYPE" != "sqlite" ]]; then print_info "Waiting for database to be fully ready..." sleep 5 fi python3 setup_database.py # Find an available port print_info "Finding available port..." PORT=8000 while lsof -i :$PORT > /dev/null 2>&1; do PORT=$((PORT + 1)) done print_success "Using port: $PORT" # Start the Django server print_info "Starting Django server on port $PORT..." print_success "Django application is now running!" print_success "🚀 Open your browser and go to: http://localhost:$PORT" print_info "Application location: $TODO_APP_DIR" print_info "To stop the server: Press Ctrl+C" print_info "" print_info "Starting server..." # Start the server python3 manage.py runserver 0.0.0.0:$PORT

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/damms005/devdb-vscode'

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