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:
Steve Yegge
2025-11-08 04:16:44 -08:00
parent 9c5bf2c1eb
commit bbe73d54bc
6 changed files with 1264 additions and 0 deletions

70
scripts/agent-mail-status.sh Executable file
View 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"

View 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"

View 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

View 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