lmcp.lua: if opts.auth_token and opts.conf are both unset, fall back to
the LMCP_TOKEN environment variable. Empty string treated as unset.
This is the primitive launchd/systemd drop-ins need — no conf file
bookkeeping on hosts that don't already use one.
scripts/lmcp-install-macos.sh: macOS installer via Homebrew. Drops the
Lua library files into $(brew --prefix)/share/lua/5.4/, mints (or
reuses) a Bearer token stored at $(brew --prefix)/etc/lmcp/token,
installs a ~/Library/LaunchAgents/ plist with LMCP_TOKEN baked in,
launchctl-loads it, and smoke-tests. Prints the Claude Code ~/.claude.json
snippet at the end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Literal string replacement with uniqueness check. Fails if old_string
is not found or matches multiple times (unless replace_all=true).
Matches the Claude Code harness Edit tool so sibling lmcp clients get
the same behaviour they already expect for in-place patches.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add MAX_BODY_SIZE (64KB) check before reading body — prevents pre-auth
OOM on internet-facing deployments
- Add JSON nesting depth limit (64 levels) — prevents C stack overflow
that bypasses pcall and crashes the process
- Timing-safe token comparison via XOR accumulate — prevents timing
oracle on Bearer token
- Auth token from LMCP_TOKEN env var (highest priority) — avoids storing
token in a file readable by the read_file tool
- Silent handling of unknown JSON-RPC notifications (spec compliance)
- Exact path matching on /mcp endpoint (was prefix-based)
- Remove dead json.array() function
Findings from architecture review + security audit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>