Skip to content

fix(bridge): gate capability-dependent LSP requests before dispatch - #260

Merged
bug-ops merged 2 commits into
mainfrom
fix/230-240-capability-gate
Aug 4, 2026
Merged

fix(bridge): gate capability-dependent LSP requests before dispatch#260
bug-ops merged 2 commits into
mainfrom
fix/230-240-capability-gate

Conversation

@bug-ops

@bug-ops bug-ops commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Check the routed server's negotiated ServerCapabilities before dispatching capability-gated requests (rename, format_document, code_actions, call_hierarchy_prepare/incoming_calls/outgoing_calls, signature_help, inlay_hints, hover, definition, references, completions, document_symbols, workspace_symbol, implementation, type_definition), returning a new typed Error::CapabilityNotSupported { server_id, capability } instead of sending the request and opaquely relaying whatever the server does with an unsupported method. handle_diagnostics is deliberately left unguarded — it falls back to the push-notification cache on pull-request failure.
  • The capability check runs before textDocument/didOpen is sent for gated handlers (new resolve_client_for_file/prepare_gated_document split).
  • Extract the Result-to-JSON/McpError mapping repeated across all 20 tool handlers in mcp/server.rs into a single to_tool_result helper.

Closes #240
Closes #230

Test plan

  • cargo +nightly fmt --all -- --check
  • cargo clippy --all-targets --all-features --workspace -- -D warnings
  • cargo nextest run --workspace --all-features --lib --bins (490 passed, 0 failed)
  • RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
  • Blocked-path test for every one of the 16 gated handler call sites
  • Positive-path test confirming dispatch proceeds when the capability is advertised
  • Explicit Some(OneOf::Left(false)) (capability explicitly unsupported, not just absent) negative test

@github-actions github-actions Bot added documentation Improvements or additions to documentation rust Rust code changes mcpls-core mcpls-core crate changes labels Aug 4, 2026
@bug-ops
bug-ops requested a lite review from Copilot August 4, 2026 18:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR strengthens the MCP↔LSP bridge by proactively gating capability-dependent LSP requests using the negotiated ServerCapabilities, and reduces boilerplate in MCP tool handlers by centralizing result-to-JSON/error mapping.

Changes:

  • Add a new bridge-layer Error::CapabilityNotSupported { server_id, capability } and use it to gate capability-dependent LSP requests before dispatch (and before didOpen for document-opening tools).
  • Refactor Translator’s dispatch preparation to split “resolve client/path” from “ensure document open”, enabling pre-open capability checks.
  • Deduplicate MCP tool handler result mapping via a shared to_tool_result helper.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/mcpls-core/src/mcp/server.rs Introduces to_tool_result helper and updates tool handlers to use it.
crates/mcpls-core/src/lsp/lifecycle.rs Adds a test-only LspServer::new_for_test fixture for capability-gate tests.
crates/mcpls-core/src/error.rs Adds Error::CapabilityNotSupported and a display test.
crates/mcpls-core/src/bridge/translator.rs Implements capability gating + pre-didOpen ordering and adds extensive tests.
CHANGELOG.md Documents the new error and behavior changes under [Unreleased].

Comment thread crates/mcpls-core/src/mcp/server.rs
Comment thread CHANGELOG.md Outdated
Comment thread crates/mcpls-core/src/lsp/lifecycle.rs
@bug-ops
bug-ops enabled auto-merge (squash) August 4, 2026 19:14
@bug-ops
bug-ops force-pushed the fix/230-240-capability-gate branch from 9c8ca49 to 9fdeb2b Compare August 4, 2026 19:15
bug-ops added 2 commits August 4, 2026 21:19
Check the routed server's negotiated ServerCapabilities before
dispatching capability-gated requests (rename, format, code actions,
call hierarchy, signature help, inlay hints, hover, definition,
references, completions, document/workspace symbols, implementation,
type definition) and return a typed CapabilityNotSupported error
instead of sending the request and opaquely relaying whatever the
server does with an unsupported method. diagnostics stays unguarded
since it falls back to the push-notification cache on failure.

Also extract the Result-to-JSON mapping repeated across all 20 tool
handlers in mcp/server.rs into a single to_tool_result helper.

Closes #240
Closes #230
Document that the capability check relies solely on the initialize-
time ServerCapabilities snapshot and does not account for dynamic
client/registerCapability. Simplify LspServer::new_for_test to use
LspClient::new instead of LspClient::from_transport, dropping two of
the three spawned placeholder processes and the dependency on
from_transport's background tokio::spawn.
@bug-ops
bug-ops force-pushed the fix/230-240-capability-gate branch from 9fdeb2b to 02a08a5 Compare August 4, 2026 19:19
@bug-ops
bug-ops merged commit fd57005 into main Aug 4, 2026
27 checks passed
@bug-ops
bug-ops deleted the fix/230-240-capability-gate branch August 4, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation mcpls-core mcpls-core crate changes rust Rust code changes

Projects

None yet

2 participants