Skip to content

fix(database): find public getMcpTools in IntelliJ 2026.2 (build 262) - #1179

Merged
catatafishen merged 3 commits into
masterfrom
fix/jetbrains-mcp-proxy-262
Oct 12, 2026
Merged

catatafishen merged 3 commits into
masterfrom
fix/jetbrains-mcp-proxy-262

Conversation

@catatafishen

@catatafishen catatafishen commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Problem

On IntelliJ 2026.2 (build 262) no database proxy tools are registered. JetBrainsMcpProxy discovers the JetBrains MCP Server plugin's tools by reflection on McpServerService.getMcpTools. Earlier builds had that method module-internal, so Kotlin mangled its name to getMcpTools$intellij_mcpserver, and that is the only name we looked up. Build 262 made it public under the plain name getMcpTools, so the lookup throws NoSuchMethodException, tool discovery fails, and the database tools are silently absent.

Fix

  • Look the method up under both names, plain name first, for both signatures: the 5-parameter one (2026.2+, with the invocation mode) and the 4-parameter one (2026.1 and earlier). Newest signature first.
  • McpToolInvocationMode, the fifth parameter's type, only exists from 2026.2, so it is loaded optionally: when it is absent the four-parameter overload is used instead of discovery failing on the missing class.
  • Extracted the lookup into findDeclaredMethod so it can be tested without the JetBrains plugin.
  • When nothing matches, the NoSuchMethodException now lists the getMcpTools* overloads that do exist on the class, so the next signature change is diagnosable from the log.
  • The warning no longer tells the user to install the "JetBrains AI Assistant" plugin (wrong plugin); it names the MCP Server plugin and mentions the signature.

Tests

JetBrainsMcpProxyTest uses small fake service classes: finds the public method (build 262), finds the mangled one (earlier builds), prefers the plain name when both exist, and returns null when no overload matches the parameter types. Selection is also tested with and without the invocation-mode class (fake services standing in for 2026.1, build 262 and early 2026.2 builds). Full plugin-core suite: 11,067 tests, 0 failures.

Not verified

The tests cover the lookup only, against fake classes. I have not re-run tool discovery against the real MCP Server plugin in a live IDE in this session, so please confirm on a 2026.2 build that the database tools show up again.

JetBrains made McpServerService.getMcpTools public, dropping the Kotlin
$intellij_mcpserver mangling. JetBrainsMcpProxy only looked up the mangled
name, so tool discovery threw NoSuchMethodException and no database proxy
tools were registered.

Probe the plain name first, then the mangled one, for both the 5- and
4-parameter signatures. When nothing matches, the error now lists the
getMcpTools overloads that do exist, and the warning no longer points at
the wrong plugin.
Copilot AI balanced review requested due to automatic review settings October 12, 2026 17:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Loading the 2026.2 invocation-mode class before the legacy fallback can break tool discovery on older supported IDEs.

1 open finding
What changed in this PR

Updates reflective MCP tool discovery for IntelliJ 2026.2 while retaining older method names and signatures.

Changes:

  • Supports public and Kotlin-mangled getMcpTools names.
  • Adds diagnostic output and focused lookup tests.
File Description
JetBrainsMcpProxy.java Updates reflective discovery and diagnostics.
JetBrainsMcpProxyTest.java Tests method-name lookup behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.86486% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ge/psi/tools/database/proxy/JetBrainsMcpProxy.java 64.86% 11 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

…ls on 2026.1

Review feedback on #1179: invokeGetMcpTools loaded com.intellij.mcpserver.McpToolInvocationMode
before probing for any overload. That class only exists from 2026.2, so on 2026.1 and earlier
Class.forName threw ClassNotFoundException and the four-parameter overload was never reached,
leaving the database tools unregistered. The original code only loaded it in the fallback for
the five-parameter overload.

- loadOptionalClass: a missing class gives null instead of aborting discovery.
- findGetMcpTools: tries the five-parameter overload only when the invocation-mode class exists,
  then falls back to the four-parameter one. The DIRECT constant is only looked up when the
  five-parameter overload was chosen.
- Tests for selection with and without the class (fake services standing in for 2026.1,
  build 262 and early 2026.2 builds), and for loadOptionalClass.
- Class Javadoc now describes both method names and the optional fifth parameter.
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

IDE Compatibility Matrix

✅ pass ❌ fail 🚫 unavailable ❓ no test yet

Generated from the real-IDE integration bench (:ide-integration-tests).

Tool CL IU RD
PSI / Navigation      
search_symbols ✅ ✅ 🚫
get_file_outline ✅ ✅ ❓
find_references ✅ ✅ ❓
go_to_declaration ✅ ✅ ❓
get_documentation ✅ ✅ ❓
get_symbol_info ✅ ✅ ❓
get_class_outline ❓ ❓ ❓
Code Quality      
get_highlights ✅ ✅ ✅
get_problems ✅ ✅ ✅
get_compilation_errors ✅ ✅ ✅
get_available_actions ❓ ❓ ❓
apply_action ❓ ❓ ❓
apply_quickfix ❓ ❓ ❓
format_code ❓ ❓ ❓
optimize_imports ❓ ❓ ❓
suppress_inspection ❓ ❓ ❓
Refactoring      
get_type_hierarchy 🚫 ✅ ❓
get_call_hierarchy 🚫 ✅ ❓
find_implementations 🚫 ✅ ❓
find_super_methods ❓ ❓ ❓
refactor ❓ ❓ ❓
convert_java_to_kotlin ❓ ❓ ❓
Testing      
run_tests ❓ ❓ ❓
list_tests ❓ ❓ ❓
run_configuration ❓ ❓ ❓
get_coverage ❓ ❓ ❓
Debug      
debug_session_start ❓ ❓ ❓
breakpoint_manage ❓ ❓ ❓
debug_evaluate ❓ ❓ ❓
debug_snapshot ❓ ❓ ❓
debug_inspect_frame ❓ ❓ ❓
debug_variable_detail ❓ ❓ ❓
debug_read_console ❓ ❓ ❓
debug_step ❓ ❓ ❓
debug_run_to_line ❓ ❓ ❓
Build      
read_build_output ❓ ❓ ❓
reload_project_model ❓ ❓ ❓

Logged IDE errors (non-gating)

Scraped from the IDE log during the run. These do not fail a matrix cell (the cell reflects the tool's MCP response) — they are listed for visibility while the bench matures.

⚠️ CL — (java.lang.InterruptedException: null)
Test: com.github.catatafishen.agentbridge.integration.GetHighlightsIntegrationTest.get_highlights returns a non-error response ⏎ You can find logs and other useful info in CI artifacts under the path getHighlights ⏎ java.lang.InterruptedException ⏎ at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:124) ⏎ at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$BuildersKt__BuildersKt(Builders.kt:87) ⏎ at kotlinx.coroutines.BuildersKt__BuildersKt.runBlockingWithParallelismCompensation(Builders.kt:63) ⏎ at kotlinx.coroutines.BuildersKt.runBlockingWithParallelismCompensation(Unknown Source) ⏎ at kotlinx.coroutines.internal.intellij.IntellijCoroutines.runBlockingWithParallelismCompensation(intellij.kt:48)
⚠️ CL — (java.lang.IllegalStateException: There is no ProgressIndicator or Job in this thread, the current job is not cancellable.)
Test: com.github.catatafishen.agentbridge.integration.GetHighlightsIntegrationTest.get_highlights returns a non-error response ⏎ You can find logs and other useful info in CI artifacts under the path getHighlights ⏎ java.lang.IllegalStateException: There is no ProgressIndicator or Job in this thread, the current job is not cancellable. ⏎ at com.intellij.openapi.progress.CoroutinesKt.runBlockingCancellable$lambda$0(coroutines.kt:153) ⏎ at com.intellij.openapi.progress.ContextKt.prepareThreadContext$lambda$0(context.kt:93) ⏎ at com.intellij.concurrency.ThreadContext.resetThreadContext(threadContext.kt:294) ⏎ at com.intellij.openapi.progress.ContextKt.prepareThreadContext(context.kt:92) ⏎ at com.intellij.openapi.progress.CoroutinesKt.runBlockingCancellable(coroutines.kt:151)

Clean as you code, for the code this PR touches:

- invokeGetMcpTools took 9 parameters (limit 7). The three classes it received only existed to
  build the base parameter-type array, so discoverTools now builds that array and passes it once
  (7 parameters).
- findDeclaredMethod probed names with getDeclaredMethod, catching NoSuchMethodException in an
  empty block silenced with //NOSONAR. It now scans the declared methods for a matching name and
  parameter types, in name-priority order, so there is no exception flow and no suppression.
- invocationModeClass is nullable by design, so the DIRECT lookup was flagged as a possible NPE.
  The four-parameter path is now taken explicitly when the class is absent.
- The fake services in the test no longer have unused parameters.
@sonarqubecloud

Copy link
Copy Markdown

@catatafishen
catatafishen merged commit b8d8f8e into master Oct 12, 2026
22 checks passed
catatafishen pushed a commit that referenced this pull request Oct 12, 2026
…ls on 2026.1

Review feedback on #1179: invokeGetMcpTools loaded com.intellij.mcpserver.McpToolInvocationMode
before probing for any overload. That class only exists from 2026.2, so on 2026.1 and earlier
Class.forName threw ClassNotFoundException and the four-parameter overload was never reached,
leaving the database tools unregistered. The original code only loaded it in the fallback for
the five-parameter overload.

- loadOptionalClass: a missing class gives null instead of aborting discovery.
- findGetMcpTools: tries the five-parameter overload only when the invocation-mode class exists,
  then falls back to the four-parameter one. The DIRECT constant is only looked up when the
  five-parameter overload was chosen.
- Tests for selection with and without the class (fake services standing in for 2026.1,
  build 262 and early 2026.2 builds), and for loadOptionalClass.
- Class Javadoc now describes both method names and the optional fifth parameter.
@catatafishen
catatafishen deleted the fix/jetbrains-mcp-proxy-262 branch October 12, 2026 18:12

This branch was successfully deployed

1 active deployment
fuzzing — 00149c62 Deployed Oct 12, 2026 by catatafishen via ClusterFuzzLite PR (address) #1636
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants