Add Agent Mail multi-workspace deployment guide and scripts
- docs/AGENT_MAIL_DEPLOYMENT.md: 10-step deployment plan for 13 workspaces - docs/AGENT_MAIL_MULTI_WORKSPACE_SETUP.md: Architecture and configuration guide - scripts/setup-agent-mail-workspace.sh: Auto-configure .envrc per workspace - scripts/start-agent-mail-server.sh: Start Agent Mail server - scripts/stop-agent-mail-server.sh: Stop Agent Mail server - scripts/agent-mail-status.sh: Monitor server and all channels Supports 3-channel setup: beads.dev, vc.dev, wyvern.dev Ready for 0.23.0 deployment with Agent Mail integration Amp-Thread-ID: https://ampcode.com/threads/T-bc960efb-3ddc-4635-8c8e-a42a6e9e67d9 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
70
scripts/agent-mail-status.sh
Executable file
70
scripts/agent-mail-status.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# View Agent Mail server status and active projects
|
||||
# Usage: ./agent-mail-status.sh
|
||||
|
||||
PORT="${AGENT_MAIL_PORT:-8765}"
|
||||
URL="http://127.0.0.1:$PORT"
|
||||
PID_FILE="${AGENT_MAIL_PID:-$HOME/agent-mail.pid}"
|
||||
|
||||
echo "=== Agent Mail Status ==="
|
||||
echo ""
|
||||
|
||||
# Check PID file
|
||||
if [[ -f "$PID_FILE" ]]; then
|
||||
PID=$(cat "$PID_FILE")
|
||||
if ps -p "$PID" > /dev/null 2>&1; then
|
||||
echo "Server Process: ✅ Running (PID: $PID)"
|
||||
else
|
||||
echo "Server Process: ⚠️ Stale PID file (process $PID not found)"
|
||||
fi
|
||||
else
|
||||
echo "Server Process: ⚠️ No PID file found"
|
||||
fi
|
||||
|
||||
# Check health endpoint
|
||||
echo ""
|
||||
echo "Server Health:"
|
||||
if HEALTH=$(curl -sf "$URL/health" 2>/dev/null); then
|
||||
echo " ✅ $(echo $HEALTH | jq -r '.status // "OK"')"
|
||||
echo " URL: $URL"
|
||||
else
|
||||
echo " ❌ UNREACHABLE at $URL"
|
||||
echo ""
|
||||
echo "Start server with:"
|
||||
echo " ./scripts/start-agent-mail-server.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# List projects
|
||||
echo ""
|
||||
echo "Active Projects:"
|
||||
if PROJECTS=$(curl -sf "$URL/api/projects" 2>/dev/null); then
|
||||
if [[ $(echo "$PROJECTS" | jq -r '. | length') -eq 0 ]]; then
|
||||
echo " (none yet)"
|
||||
else
|
||||
echo "$PROJECTS" | jq -r '.[] | " • \(.slug)\n Path: \(.human_key)"'
|
||||
fi
|
||||
else
|
||||
echo " (failed to fetch)"
|
||||
fi
|
||||
|
||||
# List reservations
|
||||
echo ""
|
||||
echo "Active File Reservations:"
|
||||
if RESERVATIONS=$(curl -sf "$URL/api/file_reservations" 2>/dev/null); then
|
||||
if [[ $(echo "$RESERVATIONS" | jq -r '. | length') -eq 0 ]]; then
|
||||
echo " (none)"
|
||||
else
|
||||
echo "$RESERVATIONS" | jq -r '.[] | " • \(.agent_name) → \(.resource_id)\n Project: \(.project_id)\n Expires: \(.expires_at)"'
|
||||
fi
|
||||
else
|
||||
echo " (failed to fetch)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Web UI: $URL/mail"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " Start: ./scripts/start-agent-mail-server.sh"
|
||||
echo " Stop: ./scripts/stop-agent-mail-server.sh"
|
||||
echo " Logs: tail -f $HOME/agent-mail.log"
|
||||
67
scripts/setup-agent-mail-workspace.sh
Executable file
67
scripts/setup-agent-mail-workspace.sh
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
# Setup Agent Mail configuration for a beads workspace
|
||||
# Usage: ./setup-agent-mail-workspace.sh [workspace-path]
|
||||
|
||||
set -e
|
||||
|
||||
WORKSPACE="${1:-$(pwd)}"
|
||||
cd "$WORKSPACE"
|
||||
|
||||
WORKSPACE_NAME=$(basename "$WORKSPACE")
|
||||
PARENT=$(basename $(dirname "$WORKSPACE"))
|
||||
HOSTNAME=$(hostname -s)
|
||||
|
||||
# Determine project ID based on workspace type
|
||||
determine_project_id() {
|
||||
local ws_name="$1"
|
||||
|
||||
case "$ws_name" in
|
||||
beads)
|
||||
echo "beads.dev"
|
||||
;;
|
||||
vc)
|
||||
echo "vc.dev"
|
||||
;;
|
||||
wyvern)
|
||||
echo "wyvern.dev"
|
||||
;;
|
||||
*)
|
||||
echo "unknown.dev"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
PROJECT_ID=$(determine_project_id "$WORKSPACE_NAME")
|
||||
AGENT_NAME="${PARENT}-${WORKSPACE_NAME}-${HOSTNAME}"
|
||||
|
||||
# Create .envrc for direnv
|
||||
cat > .envrc <<EOF
|
||||
# Agent Mail Configuration
|
||||
# Generated: $(date)
|
||||
# Workspace: $WORKSPACE
|
||||
# Coupling: $(basename "$PROJECT_ID")
|
||||
|
||||
export BEADS_AGENT_MAIL_URL=http://127.0.0.1:8765
|
||||
export BEADS_AGENT_NAME=$AGENT_NAME
|
||||
export BEADS_PROJECT_ID=$PROJECT_ID
|
||||
|
||||
# Optional: Uncomment for debugging
|
||||
# export BEADS_AGENT_MAIL_DEBUG=1
|
||||
EOF
|
||||
|
||||
echo "✅ Created .envrc in $WORKSPACE"
|
||||
echo ""
|
||||
echo "Configuration:"
|
||||
echo " BEADS_AGENT_MAIL_URL: http://127.0.0.1:8765"
|
||||
echo " BEADS_AGENT_NAME: $AGENT_NAME"
|
||||
echo " BEADS_PROJECT_ID: $PROJECT_ID"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Review .envrc and adjust if needed"
|
||||
echo " 2. Run: direnv allow"
|
||||
echo " 3. Test: bd info | grep -i agent"
|
||||
echo ""
|
||||
echo "To install direnv:"
|
||||
echo " brew install direnv"
|
||||
echo " echo 'eval \"\$(direnv hook zsh)\"' >> ~/.zshrc"
|
||||
echo " source ~/.zshrc"
|
||||
86
scripts/start-agent-mail-server.sh
Executable file
86
scripts/start-agent-mail-server.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# Start Agent Mail server in background
|
||||
# Usage: ./start-agent-mail-server.sh
|
||||
|
||||
set -e
|
||||
|
||||
AGENT_MAIL_DIR="${AGENT_MAIL_DIR:-$HOME/src/mcp_agent_mail}"
|
||||
LOG_FILE="${AGENT_MAIL_LOG:-$HOME/agent-mail.log}"
|
||||
PID_FILE="${AGENT_MAIL_PID:-$HOME/agent-mail.pid}"
|
||||
PORT="${AGENT_MAIL_PORT:-8765}"
|
||||
|
||||
# Check if server already running
|
||||
if [[ -f "$PID_FILE" ]]; then
|
||||
PID=$(cat "$PID_FILE")
|
||||
if ps -p "$PID" > /dev/null 2>&1; then
|
||||
echo "⚠️ Agent Mail server already running (PID: $PID)"
|
||||
echo " Stop it first: kill $PID"
|
||||
exit 1
|
||||
else
|
||||
echo "🗑️ Removing stale PID file"
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if directory exists
|
||||
if [[ ! -d "$AGENT_MAIL_DIR" ]]; then
|
||||
echo "❌ Agent Mail directory not found: $AGENT_MAIL_DIR"
|
||||
echo ""
|
||||
echo "Install with:"
|
||||
echo " git clone https://github.com/Dicklesworthstone/mcp_agent_mail.git $AGENT_MAIL_DIR"
|
||||
echo " cd $AGENT_MAIL_DIR"
|
||||
echo " python3 -m venv .venv"
|
||||
echo " source .venv/bin/activate"
|
||||
echo " pip install -e ."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if venv exists
|
||||
if [[ ! -d "$AGENT_MAIL_DIR/.venv" ]]; then
|
||||
echo "❌ Virtual environment not found in $AGENT_MAIL_DIR/.venv"
|
||||
echo ""
|
||||
echo "Create with:"
|
||||
echo " cd $AGENT_MAIL_DIR"
|
||||
echo " python3 -m venv .venv"
|
||||
echo " source .venv/bin/activate"
|
||||
echo " pip install -e ."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start server
|
||||
echo "🚀 Starting Agent Mail server..."
|
||||
echo " Directory: $AGENT_MAIL_DIR"
|
||||
echo " Log file: $LOG_FILE"
|
||||
echo " Port: $PORT"
|
||||
|
||||
cd "$AGENT_MAIL_DIR"
|
||||
source .venv/bin/activate
|
||||
|
||||
nohup python -m mcp_agent_mail.cli serve-http \
|
||||
--host 127.0.0.1 \
|
||||
--port "$PORT" \
|
||||
> "$LOG_FILE" 2>&1 &
|
||||
|
||||
echo $! > "$PID_FILE"
|
||||
|
||||
# Wait a moment for server to start
|
||||
sleep 2
|
||||
|
||||
# Check if server is healthy
|
||||
if curl -sf http://127.0.0.1:$PORT/health > /dev/null; then
|
||||
echo "✅ Agent Mail server started successfully!"
|
||||
echo " PID: $(cat $PID_FILE)"
|
||||
echo " Health: http://127.0.0.1:$PORT/health"
|
||||
echo " Web UI: http://127.0.0.1:$PORT/mail"
|
||||
echo ""
|
||||
echo "View logs:"
|
||||
echo " tail -f $LOG_FILE"
|
||||
echo ""
|
||||
echo "Stop server:"
|
||||
echo " kill $(cat $PID_FILE)"
|
||||
else
|
||||
echo "❌ Server failed to start"
|
||||
echo " Check logs: tail -f $LOG_FILE"
|
||||
rm -f "$PID_FILE"
|
||||
exit 1
|
||||
fi
|
||||
53
scripts/stop-agent-mail-server.sh
Executable file
53
scripts/stop-agent-mail-server.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
# Stop Agent Mail server
|
||||
# Usage: ./stop-agent-mail-server.sh
|
||||
|
||||
PID_FILE="${AGENT_MAIL_PID:-$HOME/agent-mail.pid}"
|
||||
|
||||
if [[ ! -f "$PID_FILE" ]]; then
|
||||
echo "⚠️ No PID file found: $PID_FILE"
|
||||
echo " Attempting to kill by process name..."
|
||||
|
||||
if pkill -f "mcp_agent_mail.cli serve-http"; then
|
||||
echo "✅ Killed Agent Mail server by process name"
|
||||
else
|
||||
echo "ℹ️ No Agent Mail server process found"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PID=$(cat "$PID_FILE")
|
||||
|
||||
if ! ps -p "$PID" > /dev/null 2>&1; then
|
||||
echo "⚠️ Process $PID not running (stale PID file)"
|
||||
rm -f "$PID_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "🛑 Stopping Agent Mail server (PID: $PID)..."
|
||||
kill "$PID"
|
||||
|
||||
# Wait for graceful shutdown
|
||||
for i in {1..5}; do
|
||||
if ! ps -p "$PID" > /dev/null 2>&1; then
|
||||
echo "✅ Server stopped gracefully"
|
||||
rm -f "$PID_FILE"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Force kill if needed
|
||||
if ps -p "$PID" > /dev/null 2>&1; then
|
||||
echo "⚠️ Server didn't stop gracefully, forcing..."
|
||||
kill -9 "$PID"
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
if ! ps -p "$PID" > /dev/null 2>&1; then
|
||||
echo "✅ Server stopped (forced)"
|
||||
rm -f "$PID_FILE"
|
||||
else
|
||||
echo "❌ Failed to stop server"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user