While decomposing Epic #15184, a live source/configuration sweep found that Neo's server-side value sse selects StreamableHTTPServerTransport. The approved source contract in D#15173 explicitly rejects deprecated legacy HTTP+SSE, so the current label blurs two different protocols precisely where the new Neural Link ingress should be unambiguous.
Live duplicate sweep: checked the latest 20 open issues, three broader GitHub title/body searches, the latest 30 A2A messages, Knowledge Base tickets, and active repository sources immediately before creation; no equivalent active ticket exists. Historical #9533 migrated the server implementation to Streamable HTTP without renaming the configuration value. Closed #10823 later established the current configuration policy: one canonical name per concept and no legacy alias chains.
Self-selection boundary: Neo-maintainer implementation lane because the change crosses shared server startup, AiConfig consumers, deployment artifacts, and operator migration documentation. Focused external falsifiers/tests remain welcome.
The Problem
BaseServer#connectTransport() currently treats aiConfig.transport === 'sse' as the Streamable HTTP branch and sends every other value—including a typo or future unknown value—through the stdio branch. This creates two defects:
the public server configuration names the deprecated transport while instantiating the current one;
an unsupported value can silently select stdio instead of failing closed.
The label is repeated across root, Knowledge Base, Memory Core, and GitLab Workflow server configurations; deployment Compose/Docker surfaces; Knowledge Base remote-mode gating; Memory Core startup behavior; tests; and operator guides.
The MCP client has a different contract. transportType: 'sse' genuinely selects SSEClientTransport, while streamable-http selects StreamableHTTPClientTransport. That legacy client capability must not be removed or conflated with this server-side rename.
The Architectural Reality
ai/mcp/server/BaseServer.mjs is the shared server transport-selection choke point.
ai/mcp/server/shared/services/TransportService.mjs owns the Streamable HTTP implementation and per-session server/transport factory.
Root and per-server AiConfig leaves bind transport values through NEO_TRANSPORT or a server-specific env var.
ai/services/knowledge-base/helpers/deploymentMode.mjs and Memory Core startup paths compare the current server value directly.
Docker/Compose artifacts currently publish NEO_TRANSPORT=sse.
ADR 0019 requires declarative AiConfig leaves and direct use-site reads. It forbids aliasing, env re-derivation, pass-along values, hidden defaults, runtime mutation, and defensive optional chaining.
#10823 removed prior config aliases and explicitly chose one canonical name per concept.
The Fix
Hard-rename the server-side value to streamable-http. The only supported server transport values become stdio and streamable-http.
Make BaseServer#connectTransport() an exhaustive fail-closed selector: stdio starts StdioServerTransport; streamable-http delegates to the existing shared TransportService; every other value throws before transport startup. The old sse value receives a clear migration error and must never fall through to stdio.
Update every server-owned AiConfig/template, direct server-mode consumer, shipped deployment artifact, focused test, and operator guide in one PR. Preserve the env-var names; the migration changes their value, not their identity.
Do not add a compatibility alias or a second normalization registry. Client-side sse remains supported wherever it denotes the actual legacy SSEClientTransport. Documentation may still use “SSE” when describing response framing within Streamable HTTP, but not as the name of the server transport mode.
Release-note handoff
The implementing PR must carry a release-note handoff so the later release-notes mining pass cannot lose this migration. The release notes for the first Neo release containing the change must call it out as a small breaking server-configuration change and include:
the exact operator edit: NEO_TRANSPORT=sse → NEO_TRANSPORT=streamable-http (and the equivalent AiConfig value);
the upgrade failure mode: the old server value fails startup with a migration error after this change;
the coordinated action: update Compose/Docker/configuration before or together with the Neo upgrade, then rebuild/recreate the affected MCP servers;
the boundary: client-side transportType: 'sse' and SSEClientTransport remain supported.
This is a PR handoff requirement, not a reason to keep this leaf open until release day.
Contract Ledger
Target Surface
Source of Authority
Proposed Behavior
Fallback / Compatibility
Docs
Evidence
Shared server selection
BaseServer#connectTransport()
Exhaustive stdio / streamable-http dispatch
Unknown and old sse values fail loud; never stdio fallback
JSDoc + migration note
Branch matrix + error assertions
Server AiConfig leaves
ADR 0019 + root/per-server config templates
Canonical value vocabulary is stdio or streamable-http
Same env-var names; no alias/normalizer
Config JSDoc/templates
Config construction tests
KB remote-mode gate
Direct aiConfig.transport read
Remote ingestion is enabled only for streamable-http
stdio behavior unchanged
KB deployment guides
visibility/call regressions
Memory Core transport paths
Direct aiConfig.transport read
HTTP-specific startup/identity behavior keys off streamable-http
stdio behavior unchanged
MC operator guides
focused startup tests
Docker/Compose/examples
Repository deployment artifacts
Shipped profiles set NEO_TRANSPORT=streamable-http
Operators receive an explicit v13.2 migration instruction
Cloud migration/config docs
repository sweep + container config tests
MCP client transports
ai/mcp/client/Client.mjs
sse continues to mean SSEClientTransport; streamable-http remains distinct
No client compatibility change
Client docs keep both names
existing + explicit non-regression tests
Decision Record impact
aligned-with ADR 0019 and ADR 0020; no amendment.
Decision Record
NOT_NEEDED — this corrects terminology and fail-closed dispatch within existing server/client transport authorities.
Acceptance Criteria
Every server-side AiConfig/template surface uses streamable-http as the canonical HTTP transport value; supported server values are documented as exactly stdio and streamable-http.
BaseServer#connectTransport() dispatches exhaustively: stdio starts stdio, streamable-http starts the existing shared Streamable HTTP service, and every other value throws before transport startup.
Supplying the old server value sse produces a clear migration error naming streamable-http; it never silently starts stdio.
No compatibility alias, value normalizer, duplicate transport registry, direct env re-read, or runtime AiConfig mutation is introduced.
Knowledge Base remote-ingestion mode and Memory Core HTTP-specific startup paths compare only the canonical server value and retain their stdio behavior.
Every shipped Dockerfile, Compose profile, launcher/example, and server-side test uses the canonical value.
Operator documentation calls the server mode “Streamable HTTP,” includes the v13.2 sse → streamable-http value migration, and reserves “SSE” for actual framing or legacy client transport.
The implementing PR body includes the release-note handoff above with the exact migration, old-value startup failure, coordinated operator action, and client-side non-impact.
Client-side transportType: 'sse' and SSEClientTransport remain supported and behaviorally distinct from streamable-http; focused regressions prove both client branches.
A repository-wide negative sweep finds no server-side transport === 'sse', transport !== 'sse', NEO_TRANSPORT=sse, or server documentation that still presents sse as Streamable HTTP. Legitimate client-side legacy SSE references are explicitly dispositioned.
Focused tests cover both supported server values, the old-value migration failure, an arbitrary unknown value, Knowledge Base remote-mode gating, Memory Core behavior, and client non-regression.
One PR fully delivers runtime, config, deployment, documentation, and focused tests; it resolves this leaf and only references Epic #15184.
Changed classes, methods, and config leaves satisfy Contextual Completeness JSDoc and @summary requirements.
Out of Scope
Removing SSEClientTransport or the client's legacy sse selector.
Changing the NEO_TRANSPORT or server-specific env-var names.
Adding deprecated HTTP+SSE server support.
Generalizing ConfigProvider with a new enum/alias subsystem.
Listener binding, bearer authentication, exact Neural Link projection, or the BigData proof journey.
Avoided Traps
Soft alias window: rejected because #10823 established one canonical configuration name and removed alias chains.
Silent compatibility fallback: rejected because an old or misspelled value must not change the process topology to stdio.
Global removal of the word SSE: rejected because SSE is still a legitimate response framing and a real legacy client transport.
Bundling into #15185: rejected because this migration crosses all MCP servers, deployments, tests, and docs; it is independently reviewable and should land before the new local ingress work writes more server-side sse assumptions.
Context
While decomposing Epic #15184, a live source/configuration sweep found that Neo's server-side value
sseselectsStreamableHTTPServerTransport. The approved source contract in D#15173 explicitly rejects deprecated legacy HTTP+SSE, so the current label blurs two different protocols precisely where the new Neural Link ingress should be unambiguous.Live duplicate sweep: checked the latest 20 open issues, three broader GitHub title/body searches, the latest 30 A2A messages, Knowledge Base tickets, and active repository sources immediately before creation; no equivalent active ticket exists. Historical #9533 migrated the server implementation to Streamable HTTP without renaming the configuration value. Closed #10823 later established the current configuration policy: one canonical name per concept and no legacy alias chains.
Self-selection boundary: Neo-maintainer implementation lane because the change crosses shared server startup, AiConfig consumers, deployment artifacts, and operator migration documentation. Focused external falsifiers/tests remain welcome.
The Problem
BaseServer#connectTransport()currently treatsaiConfig.transport === 'sse'as the Streamable HTTP branch and sends every other value—including a typo or future unknown value—through the stdio branch. This creates two defects:The label is repeated across root, Knowledge Base, Memory Core, and GitLab Workflow server configurations; deployment Compose/Docker surfaces; Knowledge Base remote-mode gating; Memory Core startup behavior; tests; and operator guides.
The MCP client has a different contract.
transportType: 'sse'genuinely selectsSSEClientTransport, whilestreamable-httpselectsStreamableHTTPClientTransport. That legacy client capability must not be removed or conflated with this server-side rename.The Architectural Reality
ai/mcp/server/BaseServer.mjsis the shared server transport-selection choke point.ai/mcp/server/shared/services/TransportService.mjsowns the Streamable HTTP implementation and per-session server/transport factory.NEO_TRANSPORTor a server-specific env var.ai/services/knowledge-base/helpers/deploymentMode.mjsand Memory Core startup paths compare the current server value directly.NEO_TRANSPORT=sse.The Fix
Hard-rename the server-side value to
streamable-http. The only supported server transport values becomestdioandstreamable-http.Make
BaseServer#connectTransport()an exhaustive fail-closed selector:stdiostartsStdioServerTransport;streamable-httpdelegates to the existing sharedTransportService; every other value throws before transport startup. The oldssevalue receives a clear migration error and must never fall through to stdio.Update every server-owned AiConfig/template, direct server-mode consumer, shipped deployment artifact, focused test, and operator guide in one PR. Preserve the env-var names; the migration changes their value, not their identity.
Do not add a compatibility alias or a second normalization registry. Client-side
sseremains supported wherever it denotes the actual legacySSEClientTransport. Documentation may still use “SSE” when describing response framing within Streamable HTTP, but not as the name of the server transport mode.Release-note handoff
The implementing PR must carry a release-note handoff so the later release-notes mining pass cannot lose this migration. The release notes for the first Neo release containing the change must call it out as a small breaking server-configuration change and include:
NEO_TRANSPORT=sse→NEO_TRANSPORT=streamable-http(and the equivalent AiConfig value);transportType: 'sse'andSSEClientTransportremain supported.This is a PR handoff requirement, not a reason to keep this leaf open until release day.
Contract Ledger
BaseServer#connectTransport()stdio/streamable-httpdispatchssevalues fail loud; never stdio fallbackstdioorstreamable-httpaiConfig.transportreadstreamable-httpaiConfig.transportreadstreamable-httpNEO_TRANSPORT=streamable-httpai/mcp/client/Client.mjsssecontinues to meanSSEClientTransport;streamable-httpremains distinctDecision Record impact
aligned-with ADR 0019 and ADR 0020; no amendment.Decision Record
NOT_NEEDED— this corrects terminology and fail-closed dispatch within existing server/client transport authorities.Acceptance Criteria
streamable-httpas the canonical HTTP transport value; supported server values are documented as exactlystdioandstreamable-http.BaseServer#connectTransport()dispatches exhaustively:stdiostarts stdio,streamable-httpstarts the existing shared Streamable HTTP service, and every other value throws before transport startup.sseproduces a clear migration error namingstreamable-http; it never silently starts stdio.sse→streamable-httpvalue migration, and reserves “SSE” for actual framing or legacy client transport.transportType: 'sse'andSSEClientTransportremain supported and behaviorally distinct fromstreamable-http; focused regressions prove both client branches.transport === 'sse',transport !== 'sse',NEO_TRANSPORT=sse, or server documentation that still presentssseas Streamable HTTP. Legitimate client-side legacy SSE references are explicitly dispositioned.@summaryrequirements.Out of Scope
SSEClientTransportor the client's legacysseselector.NEO_TRANSPORTor server-specific env-var names.Avoided Traps
sseassumptions.Related
Parent Epic: #15184
Source: D#15173
BLOCKS #15185
Refs #9533
Refs #10823
Origin Session ID:
5b19219a-d8ad-4505-864f-19b5eab44a45Retrieval Hint:
#15184 NEO_TRANSPORT sse streamable-http BaseServer fail closed client SSE distinction ADR 0019 #10823