Implement S7 operator connect helpers for SaaS and channels.

Add dry-run-default connect dispatcher and per-integration scripts with gitignored local capability state, docs, and unit tests. Mutations require --apply and use nemohermes/openshell only.
This commit is contained in:
Ty
2026-07-27 13:32:42 -07:00
parent 76df8b7ab6
commit d6b74c42f6
17 changed files with 2229 additions and 35 deletions
+216
View File
@@ -0,0 +1,216 @@
#!/usr/bin/env bash
# scripts/connect/connect-square.sh — S7: Square connect helper
#
# Connects Square via remote MCP (mcp.squareup.com).
# Allows: bookings, customers, catalog, inventory/location reads.
# Denies: payments, refunds, cards, checkout, payouts.
#
# Platform-first: uses nemohermes config set for MCP registration.
#
# Usage:
# ./scripts/connect/connect-square.sh [--dry-run|--apply]
# ./scripts/connect/connect-square.sh --help
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Source shared helpers
# shellcheck source=../lib/common.sh
source "$SCRIPT_DIR/../lib/common.sh"
# shellcheck source=../lib/env.sh
source "$SCRIPT_DIR/../lib/env.sh"
# shellcheck source=../lib/connect_state.sh
source "$SCRIPT_DIR/../lib/connect_state.sh"
# ── Defaults ───────────────────────────────────────────────────────────────
DRY_RUN=1
APPLY=0
# Square MCP configuration
SQUARE_MCP_URL="https://mcp.squareup.com/v1"
# Allowed tools (read-only)
SQUARE_ALLOWED_TOOLS=(
"bookings/list_bookings"
"bookings/get_booking"
"customers/list_customers"
"customers/get_customer"
"catalog/list_catalog"
"catalog/search_catalog_objects"
"inventory/list_inventory"
"locations/list_locations"
"locations/get_location"
)
# Denied tools (payment-related)
SQUARE_DENIED_TOOLS=(
"payments/*"
"refunds/*"
"cards/*"
"checkout/*"
"payouts/*"
)
# ── Parse args ─────────────────────────────────────────────────────────────
while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
cat <<EOF
Usage: $(basename "$0") [OPTIONS]
Connect Square via remote MCP.
Square MCP:
URL: $SQUARE_MCP_URL
Type: Remote MCP (HTTP/SSE)
Allowed tools (read-only):
bookings, customers, catalog, inventory, locations
Denied tools:
payments, refunds, cards, checkout, payouts
Options:
--dry-run Preview only (default)
--apply Execute mutations (prompts for Square access token)
--help Show this help
Safety:
--dry-run is the default. Use --apply to perform mutations.
The Square access token is stored via OpenShell provider store — never in .env.
Payment tools are explicitly denied in the MCP tool filter.
Examples:
$(basename "$0") --dry-run
$(basename "$0") --apply
EOF
exit 0
;;
--dry-run)
DRY_RUN=1
APPLY=0
shift
;;
--apply)
DRY_RUN=0
APPLY=1
shift
;;
*)
log_error "Unknown argument: $1"
exit 1
;;
esac
done
# ── Load .env ──────────────────────────────────────────────────────────────
load_env
SANDBOX_NAME="$(get_sandbox_name)"
log_section "Square Connect"
# ── Current state ──────────────────────────────────────────────────────────
current_status="$(get_status "square")"
if [[ -n "$current_status" ]]; then
log_info "Current status: $current_status"
fi
# ── Check prerequisites ────────────────────────────────────────────────────
require_cmd nemohermes "Install nemohermes CLI (part of NemoClaw platform)"
if ! nemohermes "$SANDBOX_NAME" status &>/dev/null 2>&1; then
log_error "Sandbox '$SANDBOX_NAME' not found. Run S4 first."
exit 1
fi
# ── Dry-run mode ───────────────────────────────────────────────────────────
if [[ $DRY_RUN -eq 1 ]]; then
log_info "[DRY-RUN] Square connect preview:"
log_info ""
log_info " MCP URL: $SQUARE_MCP_URL"
log_info " Type: Remote MCP"
log_info " Sandbox: $SANDBOX_NAME"
log_info ""
log_info " Allowed tools (read-only):"
for tool in "${SQUARE_ALLOWED_TOOLS[@]}"; do
log_info " - $tool"
done
log_info ""
log_info " Denied tools:"
for tool in "${SQUARE_DENIED_TOOLS[@]}"; do
log_info " - $tool"
done
log_info ""
log_info " Steps to connect:"
log_info " 1. Owner creates Square application at developer.squareup.com"
log_info " 2. Owner generates an OAuth access token (read scope)"
log_info " 3. Operator stores token: openshell provider set square-access-token <TOKEN>"
log_info " 4. Operator registers MCP: nemohermes $SANDBOX_NAME config set mcp_servers.square.url $SQUARE_MCP_URL"
log_info " 5. Tool allowlist/denylist applied via nemohermes config"
log_info ""
log_info " To execute: $(basename "$0") --apply"
exit 0
fi
# ── Apply mode ─────────────────────────────────────────────────────────────
log_info "Square connect (apply mode):"
log_info ""
log_info "The owner must first:"
log_info " 1. Create a Square application at developer.squareup.com"
log_info " 2. Generate an OAuth access token with read-only scope"
log_info " 3. Provide the token to the operator"
log_info ""
# Store token via OpenShell provider store
if openshell_available; then
log_info "Storing Square access token in OpenShell provider store…"
local_token=""
read -rsp "Square Access Token: " local_token
echo ""
if [[ -z "$local_token" ]]; then
log_warn "No access token provided. Skipping Square."
set_status "square" "skipped" "Operator skipped — no access token"
exit 0
fi
# Store via openshell (never echo the token).
# NOTE: Credentials passed as CLI args to openshell are briefly visible in
# /proc/*/cmdline and ps output. This is a platform limitation of openshell
# which does not yet support --from-stdin for provider values.
if openshell provider set square-access-token "$local_token" 2>&1; then
log_info "Square access token stored in provider store."
else
log_warn "Could not store token via openshell. Token may need manual setup."
log_warn "Run: openshell provider set square-access-token <TOKEN>"
fi
else
log_warn "openshell not available. Cannot store token in provider store."
log_warn "Store manually: openshell provider set square-access-token <TOKEN>"
fi
# Register MCP server
log_info "Registering Square MCP server…"
if nemohermes "$SANDBOX_NAME" config set \
mcp_servers.square.url "$SQUARE_MCP_URL" 2>&1; then
log_info "Square MCP URL registered."
else
log_warn "MCP URL registration failed (may need different config path)."
log_warn "Manual: nemohermes $SANDBOX_NAME config set mcp_servers.square.url $SQUARE_MCP_URL"
fi
# Apply tool allowlist
log_info "Applying Square tool allowlist (read-only)…"
log_info " Allowed: ${SQUARE_ALLOWED_TOOLS[*]}"
log_info " Denied: ${SQUARE_DENIED_TOOLS[*]}"
# Note: The actual tool filtering is done via mcp_servers config with
# tools.include / tools.exclude. The exact nemohermes subcommand varies
# by platform version. This is deferred until the platform CLI supports
# per-server tool filtering in a stable form.
log_info "[DEFERRED] Tool filters will be applied via nemohermes config set"
log_info " when the platform CLI supports per-server tools.include/exclude."
set_status "square" "connected" "Square remote MCP registered (read-only tools)"
log_info "Square connect complete."