feat(mcp)!: HTTP canonical transport — init registers HTTP + keepalive daemon, demote stdio (v0.10.0)#464
Merged
Merged
Conversation
…TTP + keepalive daemon, demote stdio Finish the half-done stdio→HTTP migration (ADR-0022). Breaking → v0.10.0. - mache init now registers the shared Streamable HTTP endpoint (http://localhost:7532/mcp) for Claude Code (CLI + .claude/mcp.json) and all detected editors — never a stdio command that (post-default-flip) actually starts an HTTP listener. (mache-609f70) - mache init --global installs a per-user keepalive supervisor (launchd on macOS, systemd --user on Linux) running 'mache serve --http', so the registered endpoint is answerable without babysitting 'mache serve'. The load step is test-gated (daemonAgentAutoload). (mache-605d08, achievable slice) - --stdio kept as an explicit CI/sandbox/headless escape hatch, never registered; reframed in serve --help, README, ARCHITECTURE. (mache-60dc86) - ADR-0022 records the decision; version → 0.10.0 (melange + server.json regen). On-demand socket activation + ~/.mache daemon-reliability hardening remain in mache-605d08 / mache-823d91 (decade mcp-transport-canonical).
find_smells (advisory)Scoped to files changed in this PR. Rules below run on the standalone (no-LLO) cross-ref tables; dead_code — 1 finding(s) in changed files
fan_out_skew — 3 finding(s) in changed files
Rules: the registry is |
… P2) The launchd plist and systemd unit interpolated the binary/log paths raw. os.Executable() can resolve under a path with spaces (e.g. an app bundle '/Applications/Mache Tools/mache') or — theoretically — XML-significant chars, producing a malformed supervisor file. - plist: dynamic values go through encoding/xml.EscapeText (xmlText). - systemd: ExecStart path is double-quoted with \ / " escaping (systemdQuote) so a spaced path is one argument, not whitespace-split. Tests: plist render with '/Applications/Mache & Tools/<m>ache' is asserted to be valid XML end-to-end (xml.Decoder) with metachars escaped; systemd unit quotes a spaced path.
jamestexas
added a commit
that referenced
this pull request
Jul 2, 2026
…1, mache-89e322) (#466) * [mache-89e322] docs: add frontmatter to smell-debt-baseline — fix docs:lint on main docs:lint requires covers-version + last-verified frontmatter on every top-level docs/*.md; this dated snapshot shipped without it and reddened the gate on main. Add minimal valid frontmatter (covers-version v0.8.0 to match ARCHITECTURE.md / latest CHANGELOG, last-verified = measurement date). * [mache-823d91] docs: point HTTP-daemon gotcha at `mache init --global` supervisor The keepalive supervisor shipped in v0.10.0 (#464): `mache init --global` installs a launchd LaunchAgent (macOS) or systemd --user unit (Linux) that starts + keepalives the shared HTTP daemon. GETTING-STARTED still told users it was unbuilt and "tracked in mache-823d91". Update the connection-refused gotcha to point at the shipped one-command fix. * [mache-823d91] docs: "keeps it alive" not "keepalives" (Copilot review nit) Copilot flagged "keepalives" as jargon/incorrect verb form in user-facing docs. Use the standard phrasing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Breaking change → v0.10.0. Finishes the half-done stdio→HTTP migration. See ADR-0022.
The mess this fixes
mache servedefaulted to HTTP, but the migration never finished:mache initregistered a stdio entry running baremache serve— which now starts an HTTP listener and never speaks JSON-RPC on stdout (no stdin autodetect). So the documented onboarding produced a non-working registration; only the manualclaude mcp add --transport http …worked.connection refuseduntil you ranmache servein a spare terminal.What changed (3 beads)
mache-609f70—mache initregisters the shared HTTP endpointhttp://localhost:7532/mcp(Claude CLI--transport http+{"type":"http","url":…}for.claude/mcp.json, Cursor, Windsurf, Gemini, Zed, VS Code). No stdio command, no per-client binary path.mache-605d08(achievable slice) —mache init --globalinstalls a per-user keepalive supervisor (launchd plist / systemd--userunit) runningmache serve --http localhost:7532, so the endpoint is answerable without babysitting. Supervisor load is test-gated (daemonAgentAutoload); plist/unit generation is unit-tested.mache-60dc86—--stdiokept as an explicit CI/sandbox/headless escape hatch, never registered; reframed inserve --help, README, ARCHITECTURE. ADR-0022 + version bump 0.9.0 → 0.10.0 (melange + server.json regenerated).Why HTTP-canonical is sound (not a hack)
One daemon serves every project, routing per session via the MCP roots protocol (
serve_registry.go::resolveSession→ListRoots), plus hosted (?repo=) + repo-clone modes.Tests
go test ./cmd/green (full package). Newdaemon_agent_test.gocovers plist/unit generation + file-write (load side-effect gated off).config_test/init_testupdated to assert the HTTP contract (type:http+url, nocommand/serve).go vet+golangci-lintclean.Explicitly NOT in this PR (tracked)
On-demand socket activation (spawn-on-connect) and the
~/.machedaemon-reliability hardening (stale state, singleton-socket clobber) stay inmache-605d08/mache-823d91(decademcp-transport-canonical). This PR ships canonicalization + a keepalive supervisor, not the full on-demand lifecycle.🤖 Generated with Claude Code