- Route forge-style messages to forge-related profiles instead of arbitrary *mcp* keys - Expand agent loop, custom provider, session manager, filesystem/web tools - Document local MCP server setup; extend setup-mcp-servers.sh and backlog - System prompt: Gitea list_issues vs search_issues, issues vs PRs, since/date windows Made-with: Cursor
183 lines
4.8 KiB
Bash
Executable File
183 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Clone/build local MCP servers into ./mcp-servers (local-clone policy).
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
MCP_DIR="${REPO_ROOT}/mcp-servers"
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
usage:
|
|
./scripts/setup-mcp-servers.sh <target>
|
|
|
|
targets:
|
|
gitea Clone and build gitea-mcp (Go)
|
|
proxmox-mcp-plus Clone ProxmoxMCP-Plus and pip install -e (prefers ./venv/bin/python)
|
|
|
|
notes:
|
|
- clones into ./mcp-servers/<name>
|
|
- for proxmox-mcp-plus: uses REPO/venv/bin/python if it exists, else python3 (or set NANOBOT_PYTHON)
|
|
- no second .venv under the Proxmox clone
|
|
EOF
|
|
}
|
|
|
|
need_cmd() {
|
|
local cmd="$1"
|
|
if ! command -v "${cmd}" >/dev/null 2>&1; then
|
|
echo "error: missing '${cmd}' on PATH" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
need_go_min() {
|
|
local want_major="$1"
|
|
local want_minor="$2"
|
|
|
|
local v
|
|
v="$(go version 2>/dev/null || true)"
|
|
# Example: "go version go1.26.0 linux/amd64"
|
|
local ver
|
|
ver="$(echo "${v}" | awk '{print $3}' | sed 's/^go//')"
|
|
local major minor
|
|
major="$(echo "${ver}" | cut -d. -f1)"
|
|
minor="$(echo "${ver}" | cut -d. -f2)"
|
|
|
|
if [[ -z "${major}" || -z "${minor}" ]]; then
|
|
echo "error: could not parse Go version from: ${v}" >&2
|
|
return 1
|
|
fi
|
|
|
|
# Compare major/minor only (sufficient for our use).
|
|
if (( major < want_major )) || { (( major == want_major )) && (( minor < want_minor )); }; then
|
|
echo "error: Go ${want_major}.${want_minor}+ required; found ${ver}" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
setup_gitea() {
|
|
need_cmd git
|
|
|
|
if ! command -v go >/dev/null 2>&1; then
|
|
cat <<'EOF' >&2
|
|
error: Go toolchain not found (required to build gitea-mcp).
|
|
|
|
install one of:
|
|
- Debian/Ubuntu: sudo apt-get update && sudo apt-get install -y golang
|
|
- Or install Go from https://go.dev/dl/
|
|
|
|
then rerun:
|
|
./scripts/setup-mcp-servers.sh gitea
|
|
EOF
|
|
exit 2
|
|
fi
|
|
|
|
if ! need_go_min 1 26; then
|
|
cat <<'EOF' >&2
|
|
|
|
gitea-mcp currently requires a newer Go toolchain than Debian stable typically ships.
|
|
If you already installed a newer Go under /usr/local (example: /usr/local/go1.26/bin/go),
|
|
rerun with PATH overridden, e.g.:
|
|
|
|
PATH="/usr/local/go1.26/bin:$PATH" ./scripts/setup-mcp-servers.sh gitea
|
|
EOF
|
|
exit 2
|
|
fi
|
|
|
|
mkdir -p "${MCP_DIR}"
|
|
|
|
if [[ ! -d "${MCP_DIR}/gitea-mcp/.git" ]]; then
|
|
git clone https://gitea.com/gitea/gitea-mcp.git "${MCP_DIR}/gitea-mcp"
|
|
else
|
|
echo "info: gitea-mcp already cloned, skipping clone"
|
|
fi
|
|
|
|
(cd "${MCP_DIR}/gitea-mcp" && go build -o gitea-mcp .)
|
|
|
|
echo "done: built ${MCP_DIR}/gitea-mcp/gitea-mcp"
|
|
}
|
|
|
|
need_python_min() {
|
|
local want_major="$1"
|
|
local want_minor="$2"
|
|
|
|
local v
|
|
v="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || true)"
|
|
local major minor
|
|
major="$(echo "${v}" | cut -d. -f1)"
|
|
minor="$(echo "${v}" | cut -d. -f2)"
|
|
|
|
if [[ -z "${major}" || -z "${minor}" ]]; then
|
|
echo "error: could not read Python 3 version" >&2
|
|
return 1
|
|
fi
|
|
if (( major < want_major )) || { (( major == want_major )) && (( minor < want_minor )); }; then
|
|
echo "error: Python ${want_major}.${want_minor}+ required; found ${v}" >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
setup_proxmox_mcp_plus() {
|
|
need_cmd git
|
|
need_cmd python3
|
|
if ! need_python_min 3 11; then
|
|
cat <<'EOF' >&2
|
|
|
|
proxmox-mcp-plus requires Python 3.11 or newer (see upstream pyproject requires-python).
|
|
EOF
|
|
exit 2
|
|
fi
|
|
|
|
mkdir -p "${MCP_DIR}"
|
|
|
|
if [[ ! -d "${MCP_DIR}/proxmox-mcp-plus/.git" ]]; then
|
|
git clone https://github.com/RekklesNA/ProxmoxMCP-Plus.git "${MCP_DIR}/proxmox-mcp-plus"
|
|
else
|
|
echo "info: proxmox-mcp-plus already cloned, skipping clone"
|
|
fi
|
|
|
|
if [[ -n "${NANOBOT_PYTHON:-}" ]]; then
|
|
py="${NANOBOT_PYTHON}"
|
|
elif [[ -x "${REPO_ROOT}/venv/bin/python" ]]; then
|
|
py="${REPO_ROOT}/venv/bin/python"
|
|
else
|
|
py="python3"
|
|
fi
|
|
echo "info: installing ProxmoxMCP-Plus with: ${py}"
|
|
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
|
|
echo "info: active VIRTUAL_ENV=${VIRTUAL_ENV} (interpreter should match ${py} for consistency)"
|
|
fi
|
|
"${py}" -m pip install -e "${MCP_DIR}/proxmox-mcp-plus"
|
|
|
|
if [[ ! -f "${MCP_DIR}/proxmox-mcp-plus/proxmox-config/config.json" ]]; then
|
|
cp "${MCP_DIR}/proxmox-mcp-plus/proxmox-config/config.example.json" \
|
|
"${MCP_DIR}/proxmox-mcp-plus/proxmox-config/config.json"
|
|
echo "warn: created proxmox-config/config.json from example; edit host and API token before use"
|
|
fi
|
|
|
|
echo "done: ProxmoxMCP-Plus installed editable with: ${py} -m pip install -e ..."
|
|
echo "info: point nanobot mcpServers.proxmox command at this interpreter (e.g. $(command -v "${py}" 2>/dev/null || echo "${py}"))"
|
|
}
|
|
|
|
main() {
|
|
if [[ "${#}" -ne 1 ]]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
case "$1" in
|
|
gitea) setup_gitea ;;
|
|
proxmox-mcp-plus) setup_proxmox_mcp_plus ;;
|
|
-h|--help|help) usage ;;
|
|
*)
|
|
echo "error: unknown target '$1'" >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|
|
|