#!/bin/bash
# HN-MCP Server Deployment Script
# Supports local deployment and testing
set -e # Exit on error
# Default configuration
DEFAULT_PORT=3000
PORT=$DEFAULT_PORT
TERMINATE_ONLY=false
SERVER_PID_FILE=".server.pid"
SERVER_PORT_FILE=".server.port"
# Function to show usage
show_help() {
echo "HN-MCP Server Deployment Script"
echo ""
echo "This script deploys the HN-MCP server locally for testing."
echo ""
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -p, --port PORT Port to expose (default: $DEFAULT_PORT)"
echo " -t, --terminate Terminate existing server and exit"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 # Deploy locally on default port $DEFAULT_PORT"
echo " $0 --port 8080 # Deploy locally on custom port"
echo " $0 --terminate # Stop existing server"
echo ""
echo "Note: HN API has no rate limits - enjoy unlimited requests!"
exit 0
}
# Function to terminate local server
terminate_local_server() {
echo "🔍 Looking for existing local server..."
# First, try to use the PID file (most reliable)
if [ -f "$SERVER_PID_FILE" ]; then
OLD_PID=$(cat "$SERVER_PID_FILE")
if kill -0 "$OLD_PID" 2>/dev/null; then
# Also read the port from the port file if it exists
if [ -f "$SERVER_PORT_FILE" ]; then
OLD_PORT=$(cat "$SERVER_PORT_FILE")
echo "🛑 Stopping server with PID $OLD_PID on port $OLD_PORT..."
else
echo "🛑 Stopping server with PID $OLD_PID..."
fi
kill "$OLD_PID" 2>/dev/null || true
sleep 1
# Force kill if still running
kill -9 "$OLD_PID" 2>/dev/null || true
echo "✅ Server stopped"
else
echo "ℹ️ Server PID $OLD_PID is no longer running"
fi
rm -f "$SERVER_PID_FILE"
rm -f "$SERVER_PORT_FILE"
else
echo "ℹ️ No PID file found, server may not be running"
fi
# Only check port if we're NOT in terminate-only mode
if [ "$TERMINATE_ONLY" != true ]; then
# Check if something is LISTENING on the port
PORT_PID=$(lsof -ti:$PORT -sTCP:LISTEN 2>/dev/null || true)
if [ -n "$PORT_PID" ]; then
echo "⚠️ Warning: Another process (PID: $PORT_PID) is listening on port $PORT"
echo " This might be another instance of the server not tracked by PID file"
# Get process info to help user decide
PROC_INFO=$(ps -p $PORT_PID -o comm= 2>/dev/null || echo "unknown")
echo " Process: $PROC_INFO"
if [[ "$PROC_INFO" == *"node"* ]] || [[ "$PROC_INFO" == *"npm"* ]]; then
echo " This appears to be a Node.js process, stopping it..."
kill $PORT_PID 2>/dev/null || true
sleep 1
kill -9 $PORT_PID 2>/dev/null || true
echo "✅ Port $PORT cleared"
else
echo " Not a Node.js process, leaving it alone"
echo " Please use --port to choose a different port"
exit 1
fi
fi
fi
}
# Function to deploy locally
deploy_local() {
echo "📍 Local deployment on port: $PORT"
# Check if port is available
if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
echo "❌ Port $PORT is already in use!"
echo " Please choose a different port with --port option"
exit 1
fi
# Build the project
echo "🔨 Building TypeScript..."
npm run build
# Start the server in background
echo "🏃 Starting HN-MCP server..."
HN_MCP_HTTP=true HN_MCP_PORT=$PORT npm start &
SERVER_PID=$!
# Save PID and port for future termination
echo $SERVER_PID > "$SERVER_PID_FILE"
echo $PORT > "$SERVER_PORT_FILE"
# Wait for server to be ready
echo "⏳ Waiting for server to be ready..."
RETRIES=30
while [ $RETRIES -gt 0 ]; do
# Check if the server is responding (HN-MCP doesn't have /health yet, so check MCP endpoint)
if curl -s -X POST http://localhost:$PORT/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' >/dev/null 2>&1; then
echo "✅ Server is ready!"
break
fi
sleep 1
RETRIES=$((RETRIES - 1))
echo -n "."
done
echo ""
if [ $RETRIES -eq 0 ]; then
echo "⚠️ Server failed to start properly"
echo "📋 Check the logs above for errors"
exit 1
fi
echo ""
echo "✅ Local deployment successful!"
echo "======================================"
echo "🌐 HN-MCP is running at: http://localhost:$PORT"
echo "📡 MCP endpoint: http://localhost:$PORT/mcp"
echo "🔌 Connect with Postman MCP or Claude Desktop"
echo ""
echo "📝 Server PID: $SERVER_PID (saved to $SERVER_PID_FILE)"
echo ""
echo "🧪 Test the server:"
echo " # List available tools"
echo " curl -X POST http://localhost:$PORT/mcp \\"
echo " -H 'Content-Type: application/json' \\"
echo " -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}'"
echo ""
echo " # Browse top stories"
echo " curl -X POST http://localhost:$PORT/mcp \\"
echo " -H 'Content-Type: application/json' \\"
echo " -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"browse_stories\",\"arguments\":{\"type\":\"top\",\"limit\":5}}}'"
echo ""
echo "💡 To stop the server:"
echo " $0 --terminate"
echo " or: kill $SERVER_PID"
echo ""
echo "📚 No rate limits! HN API is completely open 🎉"
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-p|--port)
PORT="$2"
shift 2
;;
-t|--terminate)
TERMINATE_ONLY=true
shift
;;
-h|--help)
show_help
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
echo "🚀 HN-MCP Server Deployment"
echo "======================================"
# Always try to terminate existing server first
terminate_local_server
# If terminate-only mode, exit here
if [ "$TERMINATE_ONLY" = true ]; then
echo "======================================"
echo "✅ Termination complete"
exit 0
fi
# Deploy locally
deploy_local