CB-614: the fleet cannot share the IDE MCP — and the lead's own IDE step is currently a no-op #117
Open
opened 2026-08-17 16:31:59 +02:00 by ltms
·
2 comments
No Branch/Tag Specified
main
worker/fleetd-612-unita-87807e-1
worker/612-b3-mcpwirings-da2b58-3
worker/612-b2-cb185-176d3a-2
worker/612-b1-completion-457459-1
worker/612-agaps-73a926-2
worker/608-sleeps-3a64ff-3
worker/621-b4520b-1
worker/618-b83894-2
worker/fleetd-615-e05481-5
worker/lead-autocompact-5f1ab2-3
worker/fleetd-613-f85deb-3
worker/fleetd-608-flaky-nudge-test-d0c2d1-3
worker/lead-context-gauge-ad404f-1
worker/gauge-wiring-9158c1-4
worker/redeploy-slowstart-ead0e5-5
worker/charter-bytes-13668c-6
worker/rollover-outcome-291483-2
worker/589-f64303-2
worker/593-1a8025-5
worker/589-fcd2aa-1
worker/568-9fdaa2-3
worker/571-attempted-outcome-5739f7-2
worker/581-completionresolver-cas-sites-0542b7-6
worker/562-loop-health-wiring-test-99611c-5
worker/562-surface-loop-health-7df5cc-4
worker/575-waiter-cleanup-sites-62ad80-1
worker/572-answer-lock-release-46a9ae-5
worker/567-probe-channel-leak-a38fc5-6
worker/551-record-before-send-7cbf56-1
worker/561-listener-fanout-survives-a-throw-61d538-2
worker/555-redeploy-main-flow-seam-65c2f5-2
worker/556-injector-owns-registration-e027a5-1
worker/552-post-restart-mktemp-abort-bc2672-4
worker/553-onstatus-completion-leak-0da881-2
worker/550-shasum-linux-196132-1
worker/538-loop-dies-on-error-4a5eeb-6
worker/426-health-coverage-ef1fd4-4
worker/504-failed-reported-clean-3cfd66-3
worker/537-capturedlog-close-e4c437-2
worker/459-broken-link-targets-cadc17-5
worker/535-appender-leak-fe74c1-1
worker/512-part2-shutdown-detection-434701-9
worker/529-logger-level-sweep-2a5533-8
worker/528-drain-gate-call-site-5de83d-7
charter/forge-mcp-vs-token
worker/521-swap-guard-unpinned-28e931-5
worker/519-probe-test-harness-d25ab8-4
worker/525-logger-level-leak-1b4eb0-6
worker/518-fleetmcp-resolver-wiring-8ef96c-1
worker/512-drain-complete-line-7edd71-3
worker/517-abort-branch-and-jar-id-41b641-2
worker/500-9e52c9-3
worker/509-4912f4-2
worker/511-9a4b23-1
worker/493-479f45-2
worker/505-03f8b2-1
worker/492-followup-detect-unclear
worker/501-a31fa0-7
worker/498-451d1c-5
worker/494-1015ce-2
worker/492-209647-1
worker/489-001902-2
worker/480-relative-handover-path-906323-1
worker/480-b-handover-skill-45bf1f-5
worker/474-followup-source-pin-f54a55-17
worker/474-charter-check-on-reload-f54a55-17
worker/466-quarantine-repeatcount-report
worker/393-opencode-skill-seeding-71854b-13
worker/469-canonical-tool-names-2a472a-16
worker/466-quarantine-escalation-5ae9c1-15
worker/446-hot-exhausted-pattern-0af580-6
worker/464-charter-tool-name-guard-a85635-12
worker/463-listfleet-default-fails-open-f1c76c-11
worker/458-invariant-5-by-purpose-862f9a-10
worker/439-coordinator-row-gate-bc032a-8
worker/449-herdr-protocol-576015-4
worker/450-abstract-spawn-599e1c-5
worker/437-ack-refuses-177d91-1
worker/444-placement-window-feb56a-2
worker/440-helddurable-derived-d462d7-13
worker/425-rework-placement-resolve-c58ba1-9
worker/421-lead-peek-held-msgs-cdbad2-10
worker/435-fixed-policy-cap-fe11de-12
worker/422-gate-state-observability-9e79d6-11
worker/431-memberregistry-live-readers-cdbad2-10
worker/424-architect-slot-hot-038b41-7
worker/422-model-gate-spawn-c29f48-6
worker/425-default-profile-live-f55534-8
worker/415-coverage-wording-2cbf9c-5
worker/416-3ad1da-1
worker/418-588283-3
worker/deterministic-stamp-race-409-3cb7b6-10
worker/armed-reads-live-config-404-ed931f-9
worker/reply-peer-refusal-391-5a34bd-7
worker/models-allowlist-aa9e9b-3
worker/ttl-stamp-race-399-f1122f-8
worker/scrub-receipt-400-316b3e-5
worker/exhaustion-detection-395-105105-6
worker/scrub-abort-394-316b3e-5
fix/scrub-uid-abort
worker/task-scrub-517574-2
worker/t386-clock-bd5b78-4
worker/t384-scrub-813790-5
worker/t381-cc-748314-2
worker/t373-336973-2
worker/t365-3920c5-3
worker/t358-6e989b-1
worker/t355-8b321c-1
worker/fleetd-369-hermetic-git-tests-e8b19a-3
worker/fleetd-368-stale-lead-binding-f5682e-2
worker/fleetd-360-deploy-units-0d3793-1
worker/359-dead-lead-tabs-f1253b-4
worker/362-worktree-skills-c03e51-3
worker/361-coord-visibility-655144-1
362-plugin-visibility-and-drift
worker/errscan-bed2ca-2
worker/amqp-log-identity-bed2ca-2
worker/withdefaults-guard-561704
worker/sleepguard-82076d-1
worker/fd334-9ee1b6-5
worker/fd348-f1ab27-4
worker/fd335-a71c35-1
worker/fd342-174a17-2
worker/fd345-490d0f-3
worker/fleetd-337-5ec7d4-21
worker/fleetd-341-af5a6b-24
worker/fleetd-339-5ca0a2-23
worker/fleetd-338-83a4a1-22
worker/fleetd-333-281f46-18
worker/fleetd-329-11bdbb-16
worker/fleetd-330-2770fb-17
worker/fix-326-50506e-15
worker/fix-324-3e9bbf-14
worker/fix-323-b8287d-13
worker/fix-316b-bd0860-11
worker/fix-318-76ca36-9
worker/fix-317-486aec-8
worker/fix-315-ce47c5-6
worker/fix-307-275890-6
worker/fix-308-b4f664-7
worker/fix-309-ec3939-8
worker/fix-310-7a3974-9
worker/fix-302-52ad0e-9
worker/fix-298-ce1acb-8
worker/fix-297-66bd11-7
worker/fix-296-104622-6
worker/fix-293-bare-closetab-eb22b5-3
worker/fix-280-gone-ask-lapse-bca98e-2
worker/fix-290-reapidle-guard-coverage-9b0dd1-1
worker/fix-285-trust-seed-8f3565-10
worker/fix-284-backend-error-seat-85912c-11
worker/fix-282-chained-ask-e6d0bb-8
worker/fix-283-teardown-leaks-f40dfa-9
worker/fix-281-pin-handler-actions-4921ac-7
worker/audit-rendezvous-lifecycle-d072ae-2
worker/audit-health-placement-1a2476-6
worker/audit-teardown-exits-e207a5-3
worker/audit-launcher-asymmetry-27e370-4
worker/audit-rest-authz-6ca53c-5
worker/investigate-275-abandon-asking-fdef52-8
worker/fix-274-worktree-leak-b0095d-7
worker/fix-273-exhausted-pattern-9665b5-6
worker/fleetd-267-model-check-bd8068-1
worker/fleetd-131-archunit-18b834-7
worker/fleetd-266-sshagent-rename-a014ff-6
worker/fleetd-184-uid-claim-8e1f31-4
worker/fleetd-184-warn-b381ee-10
worker/fleetd-184-docs-be1d12-9
worker/fleetd-257-9bf010-7
worker/fleetd-103-23a113-6
worker/fleetd-247-342356-5
worker/fleetd-116-04dea8-4
worker/fleetd-252-a830e0-3
worker/fleetd-111-7e8673-9
worker/fleetd-155c-f8ef4b-8
worker/fleetd-176-b928ca-3
worker/fleetd-249-7a7878-2
worker/cb248-composition-root-b-9acdf7-15
worker/cb148-envrc-default-fa6c82-12
worker/cb201-unit5-wiring-6c12e6-8
worker/cb241-fallback-echo-1175e9-11
worker/cb149-trust-dialog-2392a5-9
worker/cb134-148-overlay-visible-c9b986-10
worker/cb234-session-id-keyed-04e1fc-1
worker/cb201-unit3-nudge-abdf5c-6
worker/cb201-unit2-policy-c1102c-5
worker/cb201-unit4-outcome-a13bfa-7
worker/cb201-unit1-classifier-91b9b1-4
worker/cb201-227-refine-831980-3
worker/cb175-model-readback-0f085f-1
worker/cb222-charter-tmpdir-17f013-1
worker/cb226-architect-slot-race-cd3aa8-3
worker/cb224-worktree-root-group-024523-2
worker/cb-123-role-demotion-c600f7-2
worker/cb-219-opencode-roots-1f677e-1
worker/cb214-claude-session-id-b9eab4-4
worker/cb213-zdotdir-wrong-process-dd6de4-3
worker/cb211-exhaustion-classification-9546e0-2
worker/cb137-ambiguous-task-4df3d8-4
worker/cb209-agentsessionid-4dfdb6-2
worker/cb185-hostenvnames-2692b5-3
worker/cb206-opencode-sqlite-128718-2
worker/cb185-worktree-group-fc0c99-1
worker/cb-137-ask-ticket-e7760c-2
worker/cb-172-broker-uri-d36ae4-4
worker/cb-175-model-readback-76ead6-3
worker/cb-161-pane-ancestry-293510-1
worker/cb-164-rebase-885863-8
worker/cb-164-empty-scrape-false-success-1a80af-3
fix/cb-197-ticket-ttl-from-completion
worker/cb-189-remote-url-coverage-4692f3-1
worker/cb-185-blockers-027756-4
worker/cb-192-gap-log-11b631-2
worker/cb-633-fix-5f4396-3
worker/cb185-router-d6436d-3
worker/cb185-router-routing-gaps-9e9d33-3
worker/cb185-paneids-992586-2
worker/cb-633-allow-list-union-ed374b-1
worker/cb-157-credential-in-remote-url-496e44-2
worker/cb-641-health-herdr-evidence-8f1f54-6
worker/cb-640-health-msg-evidence-99c9cd-1
worker/cb-642-fleets-status-skill-bbbc40-5
cb-634-ide-mcp
worker/lead-comms-wiring-c014b9-7
worker/lead-mailbox-c19577-6
worker/autocompact-window-82bc2f-5
worker/cb-634-probe-18056f-4
worker/cb635-broker-urienv
worker/cb-632-config-retry-8e0efa-7
lead/cb-622e-claude-md
lead/cb-622-followup
worker/cb-622a-165dff-1
lead/cb-622d-opencode-mount
worker/cb-622b-717c67-2
worker/cb-622c-ab7759-3
worker/cb-617b2-20ca4b-3
worker/cb-617a-5c2f4a-1
worker/cb596-4e49ef-3
worker/cb586-10500c-1
worker/cb-606-b9343a-25
worker/cb604-1445f8-24
worker/cb582-477374-21
worker/cb584-8c2281-22
worker/cb600-e6b9a9-20
worker/cb602-ce257f-19
worker/cb601-b42837-18
worker/cb598-6c7ba7-17
worker/cb599-740fe4-16
worker/cb597-282224-15
worker/cb590fix-185e9a-10
worker/cb528-recovery-race
worker/cb594-96bead-8
worker/cb590-916766-2
worker/cb527-997d99-3
worker/cb592-env-leak-3cbf9c-1
worker/cb588-async-ticket-nudge-3218f7-5
worker/cb578b-9dcb13-6
worker/cb581-d24826-5
worker/m2-u5-ef8c42-15
worker/cb578a-516499-2
worker/cb576-01a04b-17
worker/cb579-lead-tab-acba06-20
worker/cb580-terminal-health-ed6058-21
worker/cb577-f36fdc-18
worker/cb573b-3db06f-16
worker/cb568c-f36fdc-18
worker/cb568-drop-cause-c3ac1c
worker/cb575-cancelled-notification-c3ac1c
worker/m4-sol-a2cbec-3
worker/cb574-async-ask-c3ac1c
worker/cb573-health-model-8ca857-14
worker/cb572-unknown-target-7f2e35-13
worker/u4-700706-9
worker/u3-b9fcb6-6
worker/u2-ef5b68-4
worker/u1-469dce-1-clean
worker/u1-469dce-1
worker/cb-564-health-events-70cf7e-2
worker/cb-565-recycle-drops-role-98e58f-3
worker/cb-563-missing-reply-df2866-1
worker/cb-562-readiness-gate-silent-6c23c9-3
worker/cb-560-architect-presence-da8155-1
worker/cb-561-architect-silent-off-a71cab-2
worker/cb-548-bind-architect-slot-fe1b8c-1
worker/parity-overlay-settings-5fb711-1
secrets-central-store
cb-559-hot-key-correction
cb-557-fleet-role-pools
worker/cb-553-maxload-explicit-spawn-305ee3-6
worker/cb-551-idle-lead-heartbeat-f1633c-1
worker/cb-544-drain-preserves-worktree-925fad-3
worker/cb-552-docs-sync-1cb9cf-4
worker/cb-548-rendezvous-guard-rebased
worker/cb-548-rendezvous-guard-116b53-10
worker/cb-548-authz-v2-586df6-8
worker/cb-548-authz-264363-5
salvage/cb-528b-codex-home
salvage/cb-528a-codex-launcher
CB-518-primary-flow
feature/peer-launcher-spi
cb-103-injector
v1.1.0
v1.0.0
Labels
Clear labels
blocked
needs-live-proof
ready-to-delegate
silent-default
Cannot start until something else lands. The body says what.
Merged and green, but never shown working on the running daemon. Not the same as done.
Scope, files and acceptance criteria are written. A worker can be briefed from the body alone.
A feature that compiles, passes tests, and ships turned off. Nine recurrences and counting.
No Label
Milestone
No items
No Milestone
2.0 — one operation centre, many hosts
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: fleet/fleetd#117
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Raised by the operator on 2026-08-17: "how do the fleet share IDE mcp".
Measured, not assumed. Three separate findings, in order of how urgent they are.
1. LIVE DEFECT — the IntelliJ project is not open, so the lead's mandated IDE step fails today
CLAUDE.md§"IDE MCP tools & validation workflow" tells every lead, as a mandatory step afterediting any file:
ide_sync_files, thenide_diagnostics, passingproject_path = /Users/dai.ha/LTMS/claude-bridge/bridged.That call returns an error right now:
available_projectslists only Magnolia'sdev-7.0workspace and its ~70 modules. Noclaude-bridgeproject is open in the IDE at all, under either path.Two things follow, and the second is worse than the first:
CLAUDE.mdgets an error, and the "clear all errorsand warnings" gate is never actually run.
mvn clean installstill works, so the build gate isfine — but inspections (unused params, redundant modifiers, resource leaks, "always same arg")
are exactly the class a build does not catch, and that class is currently unchecked.
CLAUDE.mdmay also name the wrong path..idea/is at the repo root(
/Users/dai.ha/LTMS/claude-bridge/.idea), not atbridged/. So the documentedproject_pathof.../claude-bridge/bridgedlooks wrong independently of the project beingclosed. Cannot confirm which is right until the project is opened.
Fix: operator reopens
claude-bridgein IntelliJ, then we re-measure whichproject_paththe tools actually accept and correct
CLAUDE.mdto match. This is not a fleet feature; it is aone-line correction plus an IDE window.
Acceptance:
ide_index_status{project_path: <the correct path>}returns a status rather thanproject_not_found, andCLAUDE.mdnames that exact path.2. Sharing the mount is trivial — and that is the trap
Both IDE MCP servers are loopback network servers, not stdio:
jetbrainshttp://localhost:64342/sseintellij-indexhttp://127.0.0.1:29170/index-mcp/streamable-httpnc -zconfirms both ports are open. Any process on this host can connect. Nothing inbridgedblocks a member from reaching them.
The only reason members do not have them is incidental: they live in the project
.mcp.json,which is
--skip-worktreeand not committed, so a member's worktree checkout has no copy. Membersdo already inherit user-scope servers from
~/.claude.json(gitea,context7,ccs-*) —so the mechanism for giving them more is already proven and would be a three-line change.
We should not make that change. Reasons in §3.
3. Why a shared IDE is the wrong shape for a fleet
(a) The IDE indexes one path per project; a member works in a different path. Members get git
worktrees under
/Users/dai.ha/LTMS/.bridged-worktrees/<name>/. Measured against the livecb401-manualworktree:project_not_found. To make it work you would have to open every worktreeas its own IntelliJ project at spawn and close it at teardown. Sum of
maxLoadacross profiles is13, so that is up to 13 IntelliJ projects indexing a fresh Maven tree at once. That is an IDE
farm, not a message bus.
(b) The IDE is single-user and stateful.
ide_sync_files,reformat_file,ide_refactor_rename,open_file_in_editorand the debugger all mutate one shared IDE. Twomembers refactoring at once collide in a way neither can observe.
jetbrainsalso exposesexecute_terminal_commandandbuild_project, which would let a member run commands in theoperator's IDE context, outside its own worktree.
(c) It does not survive 2.0. A loopback port on the operator's laptop is not reachable from
another host. Wiring the fleet to it now builds a dependency that federation has to break.
(d) It is the wrong failure mode. Best case a member gets
project_not_found— loud, fine.Worst case a path resolves against the main checkout and returns diagnostics for a different
copy of the file, clean, because the member's edit is not there. A clean result read as evidence is
the seam-vs-caller family again: three instances already this month.
4. What a member actually needs, and the shape that fits
Not the IDE. A member needs to answer "does my change compile, pass, and violate an inspection?"
It already has two of three —
mvn -f bridged/pom.xml clean installworks fine inside a worktree.The gap is inspections only.
The shape that fits a fleet is headless and per-worktree, so each member gets its own answer
with no shared state:
/Applications/IntelliJ IDEA.app/Contents/bin/inspect.sh— confirmed present on this host.which qodanafinds nothing).Not yet measured, and must be before this is planned: whether
inspect.shruns against aworktree that has no
.ideaof its own, how long it takes, and whether its findings match what theGUI reports. It is slow (minutes) and needs a project directory. Treat this section as a direction,
not a design.
Scope
2.0, not 1.1. By the 1.1 admission rule — would it still be broken with exactly one host? —
finding 1 qualifies, but 1.1 is tagged (
v1.1.0, 2026-08-17) and reopening a closed milestone fornewly-discovered scope is worse than carrying it forward. Finding 1 is an operator action, not a
code change, and needs no ticket state to happen.
Proposed outcome
CLAUDE.md'sproject_path. (finding 1, do now)wiki/13-User-Guide.md§1 ("what it is not") andwiki/11-Features.md. Right now the decisionexists only as a habit, so it will be re-litigated. (cheap, do next)
inspect.shin a worktree before committing to anything in §4.Correction to §4, and the headless question answered
The operator pushed back on my framing, and they were right. I wrote "the gap is inspections
only". That is wrong. The IDE's value is the index:
ide_find_references,ide_call_hierarchy,ide_type_hierarchy,ide_find_implementationsanswer questionsgrepcannot. A member in a worktree has none of that, and no build gate replaces it. §4 above understates
the problem — read this comment instead.
Follow-up question: can IntelliJ Community run headless?
Yes — three headless modes, all present in the Community distribution
Measured in the installed IDE at
/Applications/IntelliJ IDEA.app/Contents/bin:inspect.shformat.shremote-dev-server.sh warmup --project-dir=<p>remote-dev-server.sh <cmd> <project>macOS is supported, not rejected —
launcher.sh:99setsIS_DARWIN=1and dispatches to../MacOS/<launcher>.But what is installed on this host is Ultimate, not Community:
productCode: IU, version2026.1.2build261.24374.151. There is no CE install here.The catch — the MCP server is not IntelliJ
This is the finding that changes the design.
It is a third-party community plugin, not a JetBrains component. So "can IntelliJ run
headless" and "can the index MCP run headless" are different questions:
lsof -iTCP:29170shows PID7209, command
idea, holding the listen socket.So today there is exactly one MCP index endpoint, and it belongs to one GUI IDE, indexing one
project path.
The shape that could actually work
Two facts make a per-worktree design plausible:
McpSettings$StatecarriesserverPort, withgetDefaultServerPortand anotification.serverPortInUsepath. So N instances on N ports isnot ruled out by the plugin.
launcher.shhas aninstallPluginscommand at all (line 559). Each backend gets its own plugins directory — whichalso means the MCP plugin would have to be installed into every backend, not inherited.
Sketch:
bridgedallocates a worktree per member today. It could allocate a headless IDE backendand an MCP port alongside it, and write that port into the member's
.mcp.jsonat spawn. Portallocation per member is work
bridgedalready does for panes, so it is the right owner.What that would cost, and why Community is the better fit
Each backend indexes a full Maven tree — minutes of CPU and GBs of RAM, up to
maxLoadsum = 13at once. That cost is the real objection, not the plumbing.
On edition: Community is arguably the correct choice for the fleet, and the operator's instinct
here is right. CE is free, so N backends raise no seat question, while N Ultimate backends do. CE
covers Java, Maven and git, which is everything this repo needs; Ultimate's extras are not used by
members. The lead can stay on Ultimate.
Not verified — do not plan on these
jetbrains-index-mcp-pluginloads and serves at all inside a remote-dev backend. Itsdescription says some refactorings are "fully headless", but that means "works with no editor
open", not "works with no IDE".
warmuptiming and memory forclaude-bridgeon this host.The first bullet is the gate. If the plugin does not serve in a backend, the whole per-worktree
design collapses and the honest answer stays "members get
mvn, the lead gets the index".Next measurement, cheapest decisive one first: run
remote-dev-server.sh warmup --project-dir=<a worktree>and see whether it completes, how long ittakes, and whether anything binds an MCP port. That answers the gate without committing to a design.
Filed #162 (CB-634) to implement the member-side mount. It revisits §3 of this ticket: new measurement on the
kbhost shows the Index MCP is application-scoped and fails closed on an ambiguousproject_path, and the enabled build exposes only 16 navigation tools (no terminal/build). That makes a bounded, opt-in, per-worktree mount safe, where §3 concluded — correctly, on the evidence it had — that sharing was the wrong shape.Finding 1 here (the lead's own IDE step is a no-op / the
project_pathinCLAUDE.mdmay be wrong) stays with this ticket — it is an operator action, not part of #162.