* feat(serve): turnkey secure remote MCP server (#1877) Add `mempalace serve`: a secure-by-default wrapper over the HTTP MCP transport so a team can stand up a shared central palace with one command. Server capabilities (mempalace/mcp_server.py): - Native TLS via --tls-cert/--tls-key (env MEMPALACE_MCP_TLS_CERT/_KEY): wraps the socket in a TLS 1.2+ context, validated before bind. Token is still required on a non-loopback bind (TLS != auth). - Read-only mode via --read-only (env MEMPALACE_MCP_READ_ONLY): the 24 mutating tools are hidden from tools/list and refused at dispatch (-32003), enforced before arg handling — not merely hidden. Turnkey command (mempalace/cli.py): - Auto-generates a strong bearer token for non-loopback binds, stored 0600 under ~/.mempalace/server/ and printed once; reused across restarts. Token rides in the child env, never argv, so it can't leak via ps. - Prints a ready-to-paste client config (scheme reflects TLS), then foreground-execs the real server so Docker/systemd own the lifecycle. Deployment (deploy/): - docker-compose.server.yml wires the server + Qdrant with a /healthz healthcheck and persistent volumes. - server.env.example documents the env surface. - mempalace-server.service is a hardened systemd unit template. Tests: TLS handshake (openssl-gated), read-only enforcement, token autogen/0600/reuse, token-not-in-argv, secure-by-default gates. Docs: remote-server guide now leads with `mempalace serve` plus Compose and systemd subsections. * test(serve): fix Windows — don't patch os.name; gate 0600 asserts to POSIX Patching os.name to 'posix' broke Path.home() on Windows (pathlib mixed POSIX home resolution with Windows drive parsing). Capture both exec branches (os.execve + subprocess.run) instead, and guard the POSIX permission-bit assertions behind os.name == 'posix' (Windows files report 0o666).
29 lines
1.3 KiB
Bash
29 lines
1.3 KiB
Bash
# MemPalace remote server environment.
|
|
# Copy to deploy/.env (compose) or /etc/mempalace/server.env (systemd) and edit.
|
|
# Keep this file readable only by the service account: chmod 600.
|
|
|
|
# --- Required for a network-exposed (0.0.0.0) bind ------------------------------
|
|
# Clients send: Authorization: Bearer <this value>. Generate a strong secret:
|
|
# openssl rand -hex 32
|
|
MEMPALACE_MCP_HTTP_TOKEN=
|
|
|
|
# --- Storage backend ------------------------------------------------------------
|
|
# The team server should use a networked backend so the palace is shared.
|
|
MEMPALACE_BACKEND=qdrant
|
|
MEMPALACE_QDRANT_URL=http://qdrant:6333
|
|
# MEMPALACE_QDRANT_API_KEY=
|
|
|
|
# --- Embedding ------------------------------------------------------------------
|
|
# auto | cpu | cuda | dml | coreml. Use cuda on a GPU host (needs the GPU image).
|
|
MEMPALACE_EMBEDDING_DEVICE=auto
|
|
|
|
# --- Optional: native TLS (otherwise terminate TLS at a reverse proxy) ----------
|
|
# Point these at a PEM cert/key the service account can read. When set, serve
|
|
# speaks HTTPS directly and clients connect to https://...
|
|
# MEMPALACE_MCP_TLS_CERT=/etc/mempalace/tls/cert.pem
|
|
# MEMPALACE_MCP_TLS_KEY=/etc/mempalace/tls/key.pem
|
|
|
|
# --- Palace location (systemd / bare-metal) -------------------------------------
|
|
# In Docker the palace lives on the mempalace-data volume by default.
|
|
# MEMPALACE_PALACE_PATH=/var/lib/mempalace/palace
|