Skip to content

chore(mcp): remove dead client code and fix stale MCP docs - #14624

Draft
ogabrielluiz wants to merge 1 commit into
mainfrom
le-2213-mcp-prework-dead-code-docs
Draft

chore(mcp): remove dead client code and fix stale MCP docs#14624
ogabrielluiz wants to merge 1 commit into
mainfrom
le-2213-mcp-prework-dead-code-docs

Conversation

@ogabrielluiz

Copy link
Copy Markdown
Contributor

Pre-work ahead of the MCP protocol 2026-07-28 / python-sdk 2.0 upgrade. Everything here is correct against the current mcp<2.0 pin and none of it depends on the bump, so it can land on its own.

Net -224 / +51.

Dead code

Four things that cannot do what they claim to do:

  • _terminate_remote_session reads session_id / id off the session to build an Mcp-Session-Id header. Neither ClientSession nor BaseSession defines either attribute in 1.28.1, so the DELETE has always gone out bare. The SDK already sends the real terminate from streamablehttp_client's finally. Deleted, along with its only call in disconnect().
  • The aclose / close / iscoroutinefunction probing in _cleanup_session_by_id. ClientSession has neither method, so no branch could ever match. The task.cancel() that follows unwinds the session and transport context managers, which is the only correct close path.
  • _validate_session_connectivity had no production callers left, and with it the now-unused get_session_validation_timeout helper.
  • The "output_schema" tool metadata key is written and never read.

Also drops the langchain-mcp-adapters and fastmcp extras. Nothing in src imports either package.

One behaviour change

ValueError moves out of the fatal except tuple in the tool-building loop of update_tools and into the per-tool one.

create_input_schema_from_json_schema raises ValueError("Root schema must be type 'object'") for any tool whose inputSchema is {} or not an object, which is a shape real servers ship (an empty schema is the natural spelling for a no-argument tool). Sitting in the fatal tuple, one such tool aborted the whole listing and dropped every other tool on that server. It now skips that one tool, exactly like every other schema-processing failure already did.

New regression test covers it. It fails on main with ValueError: Failed to create tool 'bad_empty_schema' and passes here.

Known gap, stated honestly: a server whose tools all fail conversion now returns an empty toolset instead of raising, so /api/v2/mcp reports the generic "No tools found" rather than the specific cause, which survives only in the logs. That is a widening of behaviour TypeError / KeyError / friends already had, not a new failure class, and the mixed-tool case this targets is a strict improvement. Worth a follow-up on the endpoint's error reporting rather than re-introducing a fatal path here.

The guarded block does no I/O, so this cannot mask a connection or auth failure. connect_to_server, the SSRF and stdio validation, and _validate_connection_params all run above the loop and still propagate. The ValueErrors the retry loops re-raise originate outside this try as well.

Docs

Four fixes for things that are wrong today, independent of the upgrade:

  • mcp-server.mdx told users to select SSE while giving them a /streamable URL.
  • troubleshooting.mdx ran supergateway --sse against a /streamable endpoint. Now --streamableHttp.
  • LFX_MCP.md credited jlowin's third-party FastMCP package; the code imports mcp.server.fastmcp from the SDK.
  • api-reference-api-examples.mdx presented SSE as an equal option despite the (LEGACY) markers on the routes right below it. mcp-server.mdx and mcp-client.mdx carried the same sentence and are updated to match, so the three pages agree.

Versioned docs under docs/versioned_docs/ are deliberately left alone. They describe what those releases shipped.

Verification

suite result
src/lfx/tests/unit/mcp 417 passed
src/backend/tests/unit/base/mcp 292 passed, 7 skipped
src/backend/tests/unit/api/v1/test_mcp*.py 52 passed
test_run_starter_projects_backward_compatibility.py passed
ruff check src/ clean

The starter-projects test matters here: a frozen 1.6.0 flow imports MCPSseClient and passes mcp_sse_client=, so the alias and that kwarg are deliberately kept.

Notes for review

  • The two deactivated components (deactivated/mcp_sse.py, mcp_stdio.py) were on the chopping block and are not deleted. test_mcp_runtime_config_validation.py imports MCPStdio and asserts the stdio command policy is enforced before connecting, so deleting it would delete security coverage. mcp_sse.py genuinely has no coverage and could go, but splitting the pair for that seemed worse than leaving both.
  • Deleting _validate_session_connectivity meant two regression tests lost the patch.object(...)/assert_not_called() scaffolding they used to prove get_session stays off the hot path. Both now assert list_tools.assert_not_awaited() directly, which is the property they were really guarding.

Pre-work ahead of the MCP protocol 2026-07-28 upgrade. Everything here is
correct against the current mcp<2.0 pin and does not depend on the bump.

Dead code:

- Delete _terminate_remote_session and its only call. It has never sent the
  Mcp-Session-Id header it exists to send: it probes the session for
  `session_id` / `id`, and neither ClientSession nor BaseSession defines
  either attribute, so the DELETE always went out bare. The SDK already sends
  the real terminate from streamablehttp_client's finally block.
- Delete the aclose/close/iscoroutinefunction probing in
  _cleanup_session_by_id. ClientSession has neither method, so no branch could
  match. Cancelling the background task unwinds the transport context
  managers, which is the only correct close path.
- Delete _validate_session_connectivity. It had no production callers left,
  and with it the now-unused get_session_validation_timeout helper.
- Drop the write-only "output_schema" tool metadata key. Nothing reads it.

Behaviour fix:

- Move ValueError out of the fatal except tuple in the tool-building loop and
  into the per-tool one. create_input_schema_from_json_schema raises
  ValueError("Root schema must be type 'object'") for any tool whose
  inputSchema is empty or not an object, which is a shape real servers ship.
  In the fatal tuple, one such tool aborted the listing and dropped every
  other tool on that server. It now skips that tool, like every other
  schema-processing failure. Covered by a new regression test.

  The guarded block does no I/O, so this cannot mask a connection or auth
  failure: those are raised above the loop and still propagate. The one cost
  is that a server whose tools *all* fail conversion now yields an empty
  toolset rather than an exception, with the cause only in the logs.

Docs:

- mcp-server.mdx told users to select SSE while giving a /streamable URL.
- troubleshooting.mdx ran supergateway --sse against a /streamable endpoint.
- LFX_MCP.md credited the third-party FastMCP package; the code imports
  mcp.server.fastmcp from the SDK.
- api-reference presented SSE as an equal option despite the (LEGACY) markers
  on the routes just below it. mcp-server.mdx and mcp-client.mdx carried the
  same sentence and are updated to match.

Also drop two extras nothing imports, langchain-mcp-adapters and fastmcp.
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 51bf44a3-5d63-432e-88e9-fd4ba9ec344e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the chore Maintenance tasks and housekeeping label Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Build successful! ✅
Deploying docs draft.
Deploy successful! View draft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance tasks and housekeeping

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant