LearnNewsExamplesServices
Frontmatter
id16184
titleSeparate Fleet MCP target selection from wire transport
stateClosed
labels
enhancementairefactoringarchitecture
assigneesneo-gpt-emmy
createdAtJul 30, 2026, 8:41 PM
updatedAtJul 30, 2026, 10:43 PM
githubUrlhttps://github.com/neomjs/neo/issues/16184
authorneo-gpt-emmy
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[ ] 16189 Remove the one-shot Fleet MCP target migration
closedAtJul 30, 2026, 10:43 PM

Separate Fleet MCP target selection from wire transport

Closed Backlog/active-chunk-11 enhancementairefactoringarchitecture
neo-gpt-emmy
neo-gpt-emmy commented on Jul 30, 2026, 8:41 PM

Context

During #16181, the Fleet vocabulary exposed a semantic collision:

  • Fleet persists a public seat intent as mcpTransport: {mode:'remote-http', tenantId}.
  • The resolved workspace plan also labels selected MC/KB rows mode:'remote-http'.
  • Neo's actual MCP wire vocabulary is stdio or streamable-http. PR #15191 / #15188 deliberately established streamable-http as the canonical server-side name and rejects the old ambiguous server value.
  • Harness adapters then translate that canonical meaning into their own boundary grammars: streamable_http, http, vendor-specific JSON, or a local stdio-to-Streamable-HTTP command bridge.

remote-http is therefore doing two jobs. In the public registry it selects a connected target; in the resolved plan it implies a wire transport. Those are not the same axis.

Fresh duplicate sweep on 2026-07-30:

  • latest 20 open issues: no equivalent;
  • GitHub title/body search for Fleet MCP placement/target/transport naming: #16181 only, where this cleanup is explicitly out of scope;
  • Knowledge Base concept walk and team Memory Core sweep: recovered the existing Fleet implementation and #15191 naming decision, but no successor ticket;
  • structure map confirms ai/services/fleet/ and src/ai/fleet/ are the existing owners. No new subsystem is needed.

The Problem

The same remote-http string currently answers three different questions:

  1. Which Fleet target did the operator select: resident services or a connected tenant?
  2. Which transport does a resolved MCP plan row use: stdio or Streamable HTTP?
  3. Which spelling does one installed harness require at its config boundary?

This makes source and documentation misleading. A predicate such as mode === 'remote-http' may mean target selection, plan placement, or protocol rendering depending on the file. It also makes valid future combinations hard to state: a same-machine container target is non-resident but uses Streamable HTTP; a native public Connector changes reachability without changing the MCP protocol; a harness command bridge is stdio at one boundary and Streamable HTTP at the next.

Renaming every occurrence to streamable-http would not fix the model. It would merely rename target selection after a wire protocol and preserve the conflation.

The Architectural Reality

  • FleetRegistryService and FleetControlBridge own the curated public target intent. The operator chooses resident services or one connected tenant by reference; no URL, credential, header, command, or arbitrary env bag belongs there.
  • FleetTenantService resolves a tenant reference into public MC/KB resource URLs and a separate Brain-private credential.
  • prepareManagedAgentWorkspace owns the resolved per-server plan. This is where a selected target becomes a canonical MCP transport plus resource details.
  • Neo's MCP client/server transport vocabulary is stdio / streamable-http, established by #15188 / PR #15191.
  • Harness generators own vendor spelling only at the final adapter boundary. Codex's streamable_http, Claude Code's http, and Claude Desktop's command bridge are translations, not domain vocabulary.
  • This repository has one active installation. Persisted-shape migration should be one-shot and deletable; no permanent dual-name compatibility layer is warranted.

The Fix

  1. Replace the public mcpTransport target-selection shape with a target-named closed shape, semantically:

       mcpTarget: {
        kind: 'resident' | 'tenant',
        tenantId: '…' // required only for tenant
    }

    Absence may continue to mean the documented resident default if that remains the canonical registry contract. Exact field names can change during implementation only if the two axes remain explicit.

  2. Shape resolved MCP plan rows with separate fields:

       {
        target: 'resident' | 'tenant',
        transport: 'stdio' | 'streamable-http',
        // URL + credential env-slot name only when required
    }

    No steady-state plan row uses remote-http.

  3. Translate the canonical plan only inside harness adapters:

    • Codex → streamable_http;
    • Claude Code / installed vendor grammars → their exact proven HTTP spelling;
    • Claude Desktop private/local target → owned stdio command bridge;
    • local stdio servers → existing command entries.
  4. Update Fleet Registry, control bridge, AgentOS configuration round-trip, status/readback, workspace convergence receipts, lifecycle admission/readback, docs, and tests atomically.

  5. Migrate the current persisted shape once, then remove the migration path after the live registry has been rewritten and accepted. Do not retain both mcpTransport/remote-http and the replacement as permanent inputs.

  6. Add a negative vocabulary sweep that permits vendor spellings only inside named adapter boundaries and migration fixtures.

Contract Ledger

Surface Source of Authority Required Shape Failure / Migration Evidence
Public seat intent Fleet Registry + Control Bridge target selection only; no wire/vendor grammar or secret malformed/cross-axis fields reject registry/wire matrix
AgentOS configuration UI canonical AgentDefinition readback resident vs connected tenant in product language unavailable tenant rejects; no optimistic mutation store/component round-trip
Resolved MCP plan workspace composer explicit target + canonical stdio / streamable-http transport incomplete combinations reject before write plan matrix
Harness artifacts installed adapter capability translate canonical plan at final boundary only unsupported grammar fails before mutation per-adapter exact fixtures
Persisted current data one-shot migration old remote-http row becomes the new target shape once no permanent dual acceptance migration + post-migration rejection
Documentation #15191 canonical transport decision + Fleet target model distinguish target, transport, and vendor spelling no remote-http protocol claim source/docs sweep

Acceptance Criteria

  • Fleet public intent names target selection and carries only resident/tenant choice plus a tenant reference where required.
  • Resolved MCP plan rows expose target and transport as separate axes.
  • The only canonical Neo wire values are stdio and streamable-http; remote-http is absent from steady-state Fleet source, docs, fixtures, and persisted output.
  • Vendor spellings (streamable_http, http, command bridge) occur only in named harness-adapter boundaries.
  • Resident stdio, tenant Streamable HTTP, and Claude Desktop's stdio-to-Streamable-HTTP boundary are representable without contradictory field names.
  • Registry, wire, AgentOS UI round-trip, lifecycle, workspace convergence, receipt/readback, and adapter tests move atomically.
  • Existing raw-secret/header/command/env rejection remains fail-closed at the public target-intent boundary.
  • Current persisted mcpTransport:{mode:'remote-http'} state is migrated once and rewritten; the replacement does not retain a permanent compatibility alias.
  • A negative vocabulary sweep prevents remote-http from re-entering outside the bounded migration fixture.
  • Operator docs explain target selection, canonical MCP transport, and vendor translation as three distinct layers.

Out of Scope

  • Reworking the #16181 Claude Desktop bridge implementation or its lifecycle/security tests.
  • Changing MCP server protocols, authentication modes, tenant resource URLs, or credential ownership.
  • Multi-seat plane-credential cardinality.
  • Native public-Connector provisioning or private tunnel design.
  • Adding a generic transport framework or supporting hypothetical migration products.

Avoided Traps

  • Global rename to streamable-http: preserves the model defect by naming target selection after a protocol.
  • Registry-only rename: leaves resolved plan rows and predicates ambiguous.
  • Plan-only rename: leaves public operator intent pretending to be a wire transport.
  • Vendor grammar in domain state: streamable_http / http are adapter spellings, not Fleet vocabulary.
  • Permanent compatibility layer: one installation does not justify indefinite dual-shape parsing and tests.
  • Bridge-driven naming: Claude Desktop's two-boundary bridge is one consumer of the model, not the model itself.

Decision Record impact

No ADR amendment is expected. This enforces the canonical transport vocabulary already established by #15188 / PR #15191 and clarifies the existing Fleet ownership layers. Revalidate if implementation changes public credential ownership or introduces a new transport protocol.

Related

Naming authority #15188 / merged PR #15191 · original Fleet remote target #15805 / merged PR #16053 · bridge consumer #16181 / PR #16182 · hard cut #16167.

Origin Session ID: b1ebc46a-5a83-496c-aa8b-385af785e9cb

Retrieval Hint: Fleet mcpTarget remote-http target selection streamable-http transport vendor adapter vocabulary

tobiu referenced in commit af14ef6 - "feat(fleet): separate MCP target and transport (#16184) (#16190)" on Jul 30, 2026, 10:43 PM
tobiu closed this issue on Jul 30, 2026, 10:43 PM