Feature/jetbrains ide companion#10531
Conversation
Summary of ChangesHello @SoLoHiC, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new JetBrains IDE companion plugin for the Gemini CLI. The plugin aims to provide a seamless integration experience, allowing the Gemini CLI to interact directly with the IDE's workspace, including awareness of open files, selection context, and native diffing capabilities. It extends the existing IDE detection logic to support various JetBrains products and establishes a communication server to facilitate real-time context sharing and command execution, enhancing the developer workflow for Gemini CLI users within the JetBrains ecosystem. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This is an impressive contribution that adds a full-featured JetBrains IDE companion plugin. The implementation is well-structured, leveraging appropriate JetBrains APIs for UI integration and background tasks, and correctly setting up an MCP server for communication with the CLI. The changes to the core CLI for detecting JetBrains IDEs are also well-thought-out. My review focuses on a few critical and high-severity issues that could impact IDE responsiveness, stability, and data correctness. Addressing these will help ensure a high-quality experience for users.
|
If you are able to do, in commit, could you also add a button that suggests commit messages, like GitHub Copilot does? So you only have one thing. |
|
Does it maintain secure validated https and sse between extansion/ide extension/agent agent/anything with verified by each agent on all communication of source? |
|
Unsure if this is the correct place (otherwise feel free to delete comment) but here are my testing results. Any help is appreciated. setup
Building
Installation
Using
What was tested
|
|
This is a fantastic contribution- thank you! I'm sure many JetBrains users will appreciate it as well 🙏 I'll review the PR within the next few days. |
| if (ideInfoFromFile?.name && ideInfoFromFile.displayName) { | ||
| return { |
There was a problem hiding this comment.
you should just be able to set these values in the port file and not have to edit this file at all
lmk if that doesn't work
There was a problem hiding this comment.
yes skeshive, you're right. it's only a suggested code change generated by AI. Should i revert the commit
'6ba2cb9b5c2a182951865f5d6f80a1eb74113095' (including changes to detect-ide.ts, detect-ide.test.ts and ide-installer.ts) from this PR?
|
Frank r Peter?
________________________________
From: Shreya Keshive ***@***.***>
Sent: Monday, October 6, 2025 5:18 PM
To: google-gemini/gemini-cli ***@***.***>
Cc: David J Weatherspoon ***@***.***>; Comment ***@***.***>
Subject: Re: [google-gemini/gemini-cli] Feature/jetbrains ide companion (PR #10531)
@skeshive commented on this pull request.
________________________________
In packages/core/src/ide/detect-ide.ts<#10531 (comment)>:
you should just be able to set these values in the port file and not have to edit this file at all
lmk if that doesn't work
—
Reply to this email directly, view it on GitHub<#10531 (review)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ARQE53LT56EFDS7TOSLRPX33WLMDFAVCNFSM6AAAAACIIZCNFCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTGMBXGQ2DINRZHE>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Within this PR, my main purpose is to provide a feature-aligned jetbrains plugin. The feature you mentioned is also what i'd like to have, i'd suggest you address an independent issue for it(, which you definitely have my vote for) and i believe the official team of Gemini CLI will consider its priority on the whole roadmap. |
Sorry that i'm not a pro on neither ide plugin development nor app security field. it is my very personal understanding for your question:
|
Thanks for correcting me the build command mistake! My best guessing on your block is that gemini-cli haven't read the port info file which is written by plugin/extension, which is happening maybe because you were bootstrapping a default gemini instead of the customized one this PR created. Please ret-try test step 5: go back to the project root directory, install the customized gemini-cli using npm install -g . |
Thanks for the help - seems your assumption is correct. If this is the wrong place just let me know (I don't want to spam the PR - thought this might be helpful to get some feedback from linux testing ;-). What I tried:
Are there any more logs or anything I can try wich might be helpful for others? |
Yeah, I think a test on other OSs is really helpful and i'm happy to get involved with that. Back to this debug, correcting me if i'm wrong, i think the plugin starts the mcp server when ide is bootstrapping instead of when we're clicking Gemini-CLI button starting a integration with gemini-cli and I suspect one of those ports u pasted here is the mcp's port: So my another thought is to check the log of plugin: if we're seeing this, at least the plugin started the mcp server as expected. 37814 in the file name would be pid and 60248 would be port of mcp server. With these, we could add a few line of log output in the file 'ide-client.ts' to check if gemini-cli has found the file correctly. If we're not seeing this, the plugin is not starting the mcp server. we would need more log messages, especially ERROR messages, from your machine to findout where that plugin failed at starting mcp server. Again, thanks for your patient on this test. 😉 |
|
Yes you are absolutetly right. During IntelliJ start the mcp server is started: File exists and looks good: MCP server is running: Using default cli doesn't work as integration is unknown: Using your cli version: In the IntelliJ logs only |
Hi diver80, your effort is providing great insight. With these debug messages below, i realized that gemini-cli has actually detected possible connectable ide via the environment variables, but failed to establish the connection. The 1st default version, failed at code below: The 2nd customized version, failed at where within the method of validateWorkspacePath, which is a few lines later of the 1st picture:
The According to ide-companion-spec.md, port, workspace should also being provided as env var by plugin for gemini-cli as a tie-breaking discovery mechanism. For now, the code TerminalEnvVarCustomizer.kt of the jetbrains plugin side, still has some config issue that leads to GEMINI_CLI_IDE_SERVER_PORT and GEMINI_CLI_IDE_WORKSPACE_PATH failed to pre-set for integrated temrinal. Further, if the gemini-cli failed to find the discovery file and fallback to connecting ide via environmental variables, a GEMINI_CLI_IDE_SERVER_AUTH_TOKEN var is also needed besides GEMINI_CLI_IDE_SERVER_PORT. i've succeeded to reproduce this scenario by running the plugin in dev mode with IntelliJ IDEA and had a rough solution to solve this issue. Though my way of reproduce is still differ from running on linux, I believe they r caused by the same way, that how the gemini-cli is finding the parent process (, process of the IDE). I'll get back later, with a more solid commit. |
|
@diver80 ,i've fixed the environment variables export failure on the jetbrains plugin side and added a connection config fallback strategy from reading from file to reading from env on the gemini-cli core side. I've tested via dev mode in jetbrains plugin, it looks fine to me now. Please have a test on you linux os! hope this would make it work. 😂 @skeshive , i've added a few change to ide-client.ts and detect-ide.ts, which now i think it's necessary because it seems jetbrains ide propagates its sub-processes differently on different os, our current pid look-up strategy is possibly not working well for all of them (os-s * ide-s). What i did is to try reading all connection configs from envrionment variables when it's not read from config file and also try treading authToken from env var 'GEMINI_CLI_IDE_SERVER_AUTH_TOKEN' coz i found that if this is not provided, the fallback strategy in connect() metho of ide-client.ts would not work, which only provides port, workspacePath or stdio params from env vars. i'm testing this change on VS Code, Cursor, etc. but still please take a look on this change since it might have influence on all ide connections. 😂 |
|
@SoLoHiC : looks good now - connection established 👍. I'll test the integration.
|
|
hi diver80, don't forget to sign the CLA please, since it's a required action before our code being merged. 😃 |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a significant new feature: a JetBrains IDE companion plugin. The implementation is comprehensive, covering IDE context tracking, a local MCP server, and integration with the IDE's terminal. The changes to the core TypeScript code for detecting JetBrains IDEs are also well-done. My review has identified a critical issue in the server's handling of multiple client sessions, which will prevent the plugin from working correctly with more than one CLI instance at a time. I've also noted a high-severity issue in the custom HTTP transport layer where security-related parameters are declared but not implemented. Fixing the session management logic is essential for the plugin's core functionality.
| if (sessionId != null && transports.containsKey(sessionId)) { | ||
| transports[sessionId]!! | ||
| } else { | ||
| val newTransport = | ||
| StreamableHttpServerTransport( | ||
| enableJsonResponse = false, | ||
| allowedHosts = listOf("localhost", "127.0.0.1") | ||
| ) | ||
|
|
||
| newTransport.setOnSessionInitialized { newSessionId -> | ||
| LOG.info("New MCP session initialized: $newSessionId") | ||
| transports[newSessionId] = newTransport | ||
| startKeepAliveForSession(newSessionId, newTransport) | ||
| } | ||
| newTransport.setOnSessionClosed { closedSessionId -> | ||
| LOG.info("MCP session closed: $closedSessionId") | ||
| cleanupSession(closedSessionId) | ||
| } | ||
|
|
||
| mcpServer.connect(newTransport) | ||
| newTransport | ||
| } |
There was a problem hiding this comment.
The current implementation for handling new client sessions appears to be incorrect and will likely only support one active client at a time. A single mcpServer instance is being reused for all sessions. When a new client connects, a new StreamableHttpServerTransport is created and the shared mcpServer is connected to it on line 279. This overwrites the server's connection to any previous transport, effectively disconnecting older client sessions. The server will only be able to send notifications and tool responses to the last client that connected.
To properly support multiple concurrent clients, each session should be managed independently, likely with its own Server instance. A possible approach is to maintain a map of sessionId to Server instances. When a new session starts, you would create a new Server and a new Transport, connect them, and store them in the map. For subsequent requests, you would retrieve the correct instances using the session ID.
There was a problem hiding this comment.
This is an interesting issue. After a few round of discussion with gemini-cli, I found this issue may exist in both sides , vs code extension and jetbrains plugin.


full dialog history see the attachment.
ide-companion-multi-clients-issue.md
However, what i tested on both sides of vs code and jetbrains tells differently. how i tested:
I tried open 2 gemini session in the same ide window via 2 terminal windows;
then i opened files, selected code to see if the gemini-cli session detected the update.
the result is, thery're both working fine...see pictures below:
jetbrains session 1

jetbrains session 2

vs code session 1

vs code session 2

May not fixing it for now , since it looks like either exists on both side of vs code and jetbrains or it works fine on both sides.
| public class StreamableHttpServerTransport( | ||
| private val enableJsonResponse: Boolean = false, | ||
| private val enableDnsRebindingProtection: Boolean = false, | ||
| private val allowedHosts: List<String>? = null, | ||
| private val allowedOrigins: List<String>? = null, | ||
| private val eventStore: EventStore? = null, | ||
| ) : AbstractTransport() { |
There was a problem hiding this comment.
The transport includes constructor parameters for security, such as enableDnsRebindingProtection, allowedHosts, and allowedOrigins. However, these parameters are not used anywhere in the transport's implementation. There is no validation of the Host or Origin headers based on these settings.
While the risk is currently mitigated because the server binds to 127.0.0.1, this is a security flaw in the transport component itself. If this code is reused in a different context, it could be vulnerable to DNS rebinding attacks. The implementation should be completed to honor these security settings by validating incoming requests.
For example, you could add validation at the beginning of your request handlers:
if (enableDnsRebindingProtection) {
val host = adapter.getRequestHeader("Host")?.split(":")?.first()
if (host !in (allowedHosts ?: emptyList())) {
reject(adapter, 403, ErrorCode.Unknown(-32000), "Forbidden: Invalid Host header")
return
}
}
Thanks for the hint - done ✔ |
|
@skeshive, have you had a look at the review yet? It would be really great to have this in the master, as it makes developing with IntelliJ much easier. Thanks. |
|
@SoLoHiC sorry for the delay- could you share more info on how IJ sets the process id for the plugin? I can update the process detection logic in a separate PR so we don't need to make any changes in this one... the file should be the primary source of truth for the discovery |
yah @skeshive , it's fair enough to isolate the changes among process detection from this one. I'll revert the 2 commits change of the Gemini CLI core side. About how IJ set process id...I'm sorry that i don't really have a solid understanding upon it, especially when i've never really run a IJ IDE bundled with gemini plugin on Linux OS. All i could offer is that i reproduced similar detection issue when i ran plugin in debug mode (, starting a intellij community IDE via Intellij IDEA's gradle run command) and then ran gemini cli within the Intellij community IDE. I looked through log that gemini cli found the pid linked to the gradle daemon, while plugin of a intellij community IDE wrote process info using pid of IDE itself. pic 1st, log info of pid found of both dev mode ide printed and gemini cli detected and printed pic 2nd, pid that gemini cli detected links to gradle daemon process, which is how i started the whole "intellij community IDE" pic 3rd, pid that intellij community IDE used to name discovery file links to ides itself. hope these debug info helps. |
865f9f5 to
2fd8d73
Compare
|
since our PR has been existing for a while, a lot of other PRs merged into main branch. So i rebased the main branch and dropped the 2 commits for ide detection and connection logic of gemini core side. now all changes remain within a new package directory: |
…pm run build' failure
…sing env var port and workspace path not exported
…de change in terminal
…i opening a diffView
…ge info as github check actions 'Lint' required
c5c3af8 to
fbe8790
Compare
Hi @jochenkirstaetter , after a few debug run in Rider, i spotted the disconnection is happenning coz the workpsace path is not properly written in port info file. fixed it and works on my laptop. please have a try on latest build.
|
@skeshive , thank you and the team, for ur effort on reviewing this. i'll consider your proposal on releasing it as a standalone plugin while i still believe it would be more inspiring to deliver this plugin and a better user experience to all gemini-jetbrains users by packing this together with gemini itself. Thus, if you might find another good timing on pivoting to that in the future, let's try merging it again. Cheers |
|
@SoLoHiC As I said before, thanks for your work! Keep in mind that at JetBrains we’re planning our work for the next sprint, and supporting agents in our terminal as well as integrating agents better is on our plate. |
@ignatov, i'm glad to hear that u guys r working on similar features! If the community side could get involved in any way, let me know. |
|
Hi @SoLoHiC
Not sure what's the issue after fetching the latest version from your repository. Purged the local repository and got a fresh clone. Probably my bad Node.js skills ;-) Well, it doesn't work on my machine. ;-) - Which is really weird It seems that
FYI, using Rider 2025.3.0.2 Cheers |
i encountered these build failure often, after i rebased the lastest main branch. please try delete all As i suspect you haven't triggered the plugin being re-build(, sorry for the poor plugin versioning, )another solution if u installed a gemini globally already: go to |
|
Any options to resolve the stuck process? The integration and work from @SoLoHiC is too good for just leaving here undecided. |
|
hi fellow there, for the past two weeks, i've been moving this plugin into a independent repo. and till yesterday, it's published in jetbrains plugin marketplace as a independent developer. you can find it by searching 'Gemini CLI Companion' in IDE Settings -> Plugins -> Marketplace, or check out via this url.
Feel free to download it, use it, and report issues. i'll try keeping it up with the latest ide-companion-spec required, but no much promises :P, happy coding there. Special thanks to @diver80' help on debugging and pushing this moving forward. |
|
@SoLoHiC Thanks for your continued effort - highly appreciated. Just added the first 5 star rating in the marketplace. |
|
Hi @SoLoHiC, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this. We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines. Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed. Thank you for your understanding and for being a part of our community! |
|
Thank you for submission to the Gemini CLI project. At this time, we are closing this pull request in order to allow us to better triage and support more recent pull requests against the latest code changes. If you feel like this pull request is a critical contribution to the Gemini CLI project, please associate the pull request with an existing GitHub issue (instructions here: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) before reopening. After Monday January 26 2026, any pull requests submitted by contributors without an associated issue will be automatically closed (more information here: #16706). If you do choose to reopen and submit this pull request, please ensure you rebase your changes onto the current main branch before resubmitting. This will help avoid merge conflicts and ensure your contribution is compatible with the latest codebase. |











TLDR
Really liked Gemini-CLI and can't wait for it working within IntelliJ IDEA and other JetBrains IDE. So I took a few days during this vacation working on this plugin(, well, most of the code is actually written by Gemini itself and I'm just co-piloting along , dealing with a few tricky issues about how the MCP's streamable http transport works in Kotlin and making sure its UI works as expected.
This PR creates a JetBrains plugin providing similar features like the VS Code companion extension does. As I've tested locally, it should basically follow the https://github.com/google-gemini/gemini-cli/blob/main/docs/ide-integration/ide-companion-spec.md.
Dive Deeper
All code changes can be found under packages/jebrains-ide-companion/ .
Reviewer Test Plan
the way i tested it after pulling the code:
npm run buildpackages/jebrains-ide-companion/build/distributions/npm install -g .geminiin the JetBrains IDE's Terminal window/ide statuswithin gemini-cli, should be showing ' Connected to IntelliJ IDEA 2025.2'And also, other main features like the VSCode extension provided can be test too. Demo result below:

Testing Matrix
Linked issues / bugs
I see there already is an issue created by alcarraz, (#9273)
skeshive , please take a look at this and thanks for your work on the VS Code extension.