Skip to main content
Glama
stop.sh4.3 kB
#!/usr/bin/env bash # Stop MCP Server (repo-level wrapper, prefers installed target if present) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Default installation directory: enforce $HOME/MCPServer for user installs INSTALL_DIR="${INSTALL_DIR:-$HOME/MCPServer}" # If an installed runtime exists under INSTALL_TARGET use that first if [ -n "${INSTALL_TARGET:-}" ] && [ -x "$INSTALL_TARGET/bin/stop.sh" ]; then exec "$INSTALL_TARGET/bin/stop.sh" "$@" fi # Normalize .env line endings and source it when present if [ -f "$INSTALL_DIR/.env" ]; then if command -v dos2unix >/dev/null 2>&1; then dos2unix "$INSTALL_DIR/.env" >/dev/null 2>&1 || true else if grep -q $'\r' "$INSTALL_DIR/.env" >/dev/null 2>&1; then sed -i 's/\r$//' "$INSTALL_DIR/.env" || true fi fi set -a # shellcheck source=/dev/null source "$INSTALL_DIR/.env" || true set +a fi if [ ! -d "$INSTALL_DIR" ]; then echo "Installation directory not found: $INSTALL_DIR" >&2 exit 0 fi PIDFILE="${PIDFILE:-$INSTALL_DIR/run/mcp-server.pid}" PGIDFILE="${PGIDFILE:-$INSTALL_DIR/run/mcp-server.pgid}" if [ ! -f "$PIDFILE" ]; then echo "PID file not found; server not running or already stopped." >&2 exit 0 fi PID=$(cat "$PIDFILE" 2>/dev/null || echo "") if [ -z "$PID" ]; then echo "PID file empty or unreadable; removing and exiting." >&2 rm -f "$PIDFILE" || true exit 0 fi # Verify that PID points to our python/uvicorn/server.py process. If not, # treat as stale (to avoid killing unrelated PIDs) and remove pidfile. if [ -f "/proc/$PID/cmdline" ]; then CMDLINE=$(tr '\0' ' ' < /proc/$PID/cmdline) if ! echo "$CMDLINE" | grep -E "(python|uvicorn|server.py)" >/dev/null 2>&1; then echo "PID $PID does not look like our server process: $CMDLINE" >&2 echo "Removing stale pidfile." >&2 rm -f "$PIDFILE" || true rm -f "$PGIDFILE" || true exit 0 fi fi # If we have a process group id, attempt to stop the whole group first if [ -f "$PGIDFILE" ]; then PGID=$(cat "$PGIDFILE" 2>/dev/null || echo "") if [ -n "$PGID" ]; then echo "Stopping process group $PGID..." kill -TERM -"$PGID" 2>/dev/null || true # wait up to 8 seconds for graceful shutdown for i in {1..8}; do if ! kill -0 -"$PGID" >/dev/null 2>&1; then break fi sleep 1 done if kill -0 -"$PGID" >/dev/null 2>&1; then echo "Process group $PGID did not stop; force killing..." kill -KILL -"$PGID" 2>/dev/null || true fi rm -f "$PGIDFILE" || true fi fi # Fallback: stop main PID if still running if kill -0 "$PID" >/dev/null 2>&1; then echo "Stopping PID $PID..." kill -TERM "$PID" 2>/dev/null || true # wait up to 6 seconds for graceful shutdown for i in {1..6}; do if ! kill -0 "$PID" >/dev/null 2>&1; then break fi sleep 1 done if kill -0 "$PID" >/dev/null 2>&1; then echo "PID $PID did not exit, force killing..." kill -KILL "$PID" 2>/dev/null || true fi else echo "Process $PID not running; cleaning up pidfile." >&2 fi rm -f "$PIDFILE" || true echo "Stopped" # Extra fallback: detect stray listeners on common ports and kill python/uvicorn processes for PORT in ${MCP_PORT:-3000} 8000; do PIDS="" if command -v lsof >/dev/null 2>&1; then PIDS=$(lsof -t -iTCP:"$PORT" -sTCP:LISTEN 2>/dev/null || true) else if command -v ss >/dev/null 2>&1; then PIDS=$(ss -ltnp 2>/dev/null | grep -F ":$PORT " | grep -oP 'pid=\K[0-9]+' || true) fi fi for p in $PIDS; do if [ -f "/proc/$p/cmdline" ]; then CMD=$(tr '\0' ' ' < /proc/$p/cmdline) if echo "$CMD" | grep -E "(python|uvicorn|server.py)" >/dev/null 2>&1; then echo "Killing stray process $p listening on port $PORT: $CMD" kill -TERM "$p" 2>/dev/null || true sleep 1 if kill -0 "$p" >/dev/null 2>&1; then kill -KILL "$p" 2>/dev/null || true fi fi fi done done

Latest Blog Posts

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/dnchandra/mcp_linux'

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