#!/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