# neuron-connectd — local-dev stub `connectd_service.py` is a **minimal local-dev stub**, not the real sidecar. It exists to close a real local-build/local-run correctness gap found during the 2026-08-15 build audit, without taking on the much larger product task of actually building the full MCP-connector sidecar. ## The gap this closes `routes.el` (`handle_connectors`, `connectd_get`/`connectd_post`) and `chat.el` (`connector_tools_json`, the `mcp__*` branch in `dispatch_tool`, `tool_auto_approved`) are live, current code that calls `127.0.0.1:7771` on every soul boot and every agentic turn, per the design in `neuron-technologies/docs/research/mcp-connectors-adoption-spec.md` (2026-06-13, "Status: Draft for build"). That spec's sidecar — `neuron-connectd`, a TypeScript/Python process using the official MCP SDK — was never built. Nothing on disk implements it (verified: no `neuron-connectd` source anywhere under `~/Development` before this directory). Meanwhile port `:7771` is *also* claimed by two other, unrelated things: - `soul.el`'s `axon_base` default (`http://localhost:7771`) — a **different**, independently-known, already-documented gap (`platform/protocols/axon` is an unbuilt Rust crate; see `cli/HANDOFF.md` and `HANDOFF-engram-write-corruption.md`). Out of scope here — no source to build against. - `council/council_service.py --port 7771` (`ai.neuron.council` LaunchAgent) — a real, running, **unrelated** anti-confabulation service that happens to bind the same port. In Will's live environment this is what's actually listening on `:7771` today, and it answers the connector/axon requests above with its own unrelated 404 JSON body — worse than a clean connection-refused, because `chat.el`'s "bridge down" fallback expects either a real reply or nothing, not a wrong-shaped reply from an unrelated service. ## What this stub does and does not do Implements exactly the spec's documented HTTP contract (`GET /mcp/tools`, `POST /mcp/call`, `GET /mcp/servers`, `POST /mcp/servers/{add,toggle, auto-approve,remove,secret}`, `POST /mcp/oauth/start`, `GET /healthz`), always answering as if **zero connectors are configured** — empty tool list, empty server list, a clear `"not configured"` error on any call that would need a real connector. This is the *correct* steady state for a fresh local dev box that hasn't set up any MCP connectors, and it's what `chat.el`'s `connector_tools_json()` / `tool_auto_approved()` already gracefully degrade to when the bridge replies emptily. It does **not**: spawn any real MCP server, do OAuth, read or write `~/.neuron/connectors.json`, or namespace/proxy real `tools/call` traffic to Google Drive/GitHub/Slack/etc. Building that is the real product task the spec describes — a genuine, sizeable engineering lift (MCP SDK client, OAuth + Keychain token storage, per-server process lifecycle), not something to improvise inside a build/run audit. **That decision is Will's to make**, not this audit's to guess at. ## Running it ```bash # Foreground, on a throwaway port (never :7771 while council owns it live): python3 connectd_service.py --port 17771 # Verify the contract: curl -s http://127.0.0.1:17771/healthz curl -s http://127.0.0.1:17771/mcp/tools curl -s http://127.0.0.1:17771/mcp/servers ``` ## Open question for Will — the :7771 collision Three independent things are hardcoded to `:7771`: axon (unbuilt), connectd (this stub), and council (the one actually running). Wiring this stub into the real LaunchAgent stack on `:7771` requires either moving council off that port or deciding connectd should live elsewhere and repointing `routes.el`/ `chat.el`'s hardcoded `127.0.0.1:7771` calls. Neither change was made here — it touches a live, running production service (`ai.neuron.council`) and a port number baked into shipped `.el` source, both bigger than this audit's "make local build/run work" mandate. Flagging for a decision rather than guessing.