<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Henrik Westergård</title>
    <description>The latest articles on Forem by Henrik Westergård (@catatafishen).</description>
    <link>https://forem.com/catatafishen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3842125%2F2013ab2e-2476-402c-9e25-5533df0a3c13.jpeg</url>
      <title>Forem: Henrik Westergård</title>
      <link>https://forem.com/catatafishen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/catatafishen"/>
    <language>en</language>
    <item>
      <title>The Case for IDE-Native Coding Agents</title>
      <dc:creator>Henrik Westergård</dc:creator>
      <pubDate>Fri, 01 May 2026 09:04:56 +0000</pubDate>
      <link>https://forem.com/catatafishen/the-case-for-ide-native-coding-agents-5i4</link>
      <guid>https://forem.com/catatafishen/the-case-for-ide-native-coding-agents-5i4</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/catatafishen/agentbridge" rel="noopener noreferrer"&gt;AgentBridge&lt;/a&gt; is one concrete experiment in keeping agentic coding close to the way many of us already work in a full IDE.&lt;/p&gt;

&lt;p&gt;Historically, developers have often split into two broad camps. Some prefer lightweight editors because they are fast, flexible, and stay out of the way. Others prefer full IDEs like IntelliJ IDEA and the rest of the JetBrains family because the IDE constantly keeps more of the project in view: types, inspections, refactorings, tests, Git state, database connections, run configurations, and framework knowledge.&lt;/p&gt;

&lt;p&gt;Both approaches have their place. The right tool depends on the project, the language, the team, and how much infrastructure the IDE can understand. Personally, I have always preferred IntelliJ. Even when it feels heavier, it helps me work in a fail-fast way: I quickly see when something is wrong, I get warnings before problems become bugs, and weak warnings often explain why the code I just wrote is not quite right yet. Plugins such as SonarQube for IDE make that feedback loop even stronger.&lt;/p&gt;

&lt;p&gt;In the current agentic coding world, the lightweight-editor model seems to be winning. The human often moves from a full IDE into an agent wrapper, terminal harness, or chat-first environment. The agent also works mostly through file reads, text edits, shell commands, and maybe a few language-server-style helpers. Lately there has been good progress on adding symbol search, semantic editing, and highlight-reading through MCP servers, but I still think that is only a fraction of what an IDE like IntelliJ enables.&lt;/p&gt;

&lt;p&gt;The important difference is not only that the agent can ask the IDE a question. It is whether the agent is working through the IDE in the same feedback loop a human would.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related work and external references
&lt;/h2&gt;

&lt;p&gt;AgentBridge is not the only attempt to improve the interface between agents and development tools. The broader ecosystem is clearly moving from "prompt plus shell" toward richer, more structured interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; is probably the most visible example. The project describes MCP as "an open-source standard for connecting AI applications to external systems" and compares it to "a USB-C port for AI applications". That is exactly the direction AgentBridge depends on: agents should not need to rediscover everything from raw text if a better tool interface exists. AgentBridge's narrower bet is that a JetBrains IDE is one of the most valuable external systems to connect.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://microsoft.github.io/language-server-protocol/" rel="noopener noreferrer"&gt;Language Server Protocol&lt;/a&gt; is another important precedent. It standardized how editors get language features such as autocomplete, go to definition, and hover documentation from a language server. LSP made language intelligence more portable across tools, and many agent integrations now expose LSP-like symbol search or diagnostics. I think that is useful, but still smaller than the full IDE surface. JetBrains' &lt;a href="https://plugins.jetbrains.com/docs/intellij/psi.html" rel="noopener noreferrer"&gt;Program Structure Interface&lt;/a&gt; is described as the layer that creates the "syntactic and semantic code model" powering platform features. AgentBridge tries to expose more of that platform, not only the few features that fit neatly into an LSP-shaped box.&lt;/p&gt;

&lt;p&gt;The SWE-agent paper and project also make a useful point in the title alone: &lt;a href="https://arxiv.org/abs/2405.15793" rel="noopener noreferrer"&gt;"Agent-Computer Interfaces Enable Automated Software Engineering"&lt;/a&gt;. Their open-source project focuses on agents autonomously using tools to fix real GitHub issues. That framing matters: the interface you give the agent changes what the agent can do. AgentBridge agrees with that thesis, but explores a different interface: not primarily a terminal-centric computer interface, but an IDE-native one.&lt;/p&gt;

&lt;p&gt;Hooks are another path the ecosystem is exploring. Claude Code documents hooks as &lt;a href="https://code.claude.com/docs/en/hooks" rel="noopener noreferrer"&gt;"user-defined shell commands, HTTP endpoints, or LLM prompts"&lt;/a&gt; that run at specific lifecycle points, including before and after tool use. I think hooks are valuable, especially when they call deterministic tools. My concern is mostly timing and synchronization: if a hook fixes or reformats something after the agent's edit, the agent may already be reasoning from stale context. AgentBridge tries to make that feedback part of the same IDE-aware tool response when possible.&lt;/p&gt;

&lt;p&gt;The JetBrains documentation also backs the core IDE-native argument. IntelliJ inspections &lt;a href="https://www.jetbrains.com/help/idea/code-inspection.html" rel="noopener noreferrer"&gt;"detect and correct abnormal code ... before you compile it"&lt;/a&gt; and can find probable bugs, dead code, spelling problems, and structural issues. &lt;a href="https://www.jetbrains.com/help/idea/intention-actions.html" rel="noopener noreferrer"&gt;Intention actions&lt;/a&gt;&lt;br&gt;
are described as the IDE analyzing code as you work and searching for ways to optimize it. &lt;a href="https://www.jetbrains.com/help/idea/refactoring-source-code.html" rel="noopener noreferrer"&gt;Refactoring support&lt;/a&gt; is documented as a first-class IDE workflow with previews, conflict handling, and popular automated refactorings. These are exactly the kinds of deterministic, context-rich capabilities I want agents to use directly instead of approximating with text edits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fail fast matters even more for agents
&lt;/h2&gt;

&lt;p&gt;When a human edits code in IntelliJ, feedback appears immediately. Imports are suggested. Errors and warnings are highlighted. Intentions and quick-fixes show up while the surrounding context is still fresh in the developer's head.&lt;/p&gt;

&lt;p&gt;Many agents do not get that loop. They edit a file, continue with the task, and only later run a separate check if prompted or if a hook tells them to. By then the agent may have lost some of the local reasoning that led to the edit. I have seen agents implement a feature, later review their own code, find a warning, and then "fix" the warning by changing behavior that was actually required. The problem was detected, but too late in the reasoning flow.&lt;/p&gt;

&lt;p&gt;AgentBridge tries to surface IDE feedback immediately in the tool response. If an edit creates highlights, formatting changes, or import changes, the agent can react while it still remembers why it made the edit. That keeps the warning tied to the original goal instead of turning it into a separate clean-up task with weaker context.&lt;/p&gt;

&lt;p&gt;For agents, this fail-fast loop is not a luxury. It helps prevent expensive circles: edit, scan, forget, overcorrect, rebuild, rediscover the original requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strict quality gates fit agentic development
&lt;/h2&gt;

&lt;p&gt;Strict gates such as test coverage requirements, cyclomatic complexity limits, duplication checks, and static-analysis rules have always been valuable, but there has traditionally been a real tradeoff. Human teams have to decide how much time to spend refactoring working code versus building the next feature.&lt;/p&gt;

&lt;p&gt;Agentic development changes that tradeoff. Asking an agent to satisfy a coverage threshold, split a complex method, or clean up a warning is much cheaper than asking a human to spend the same focus time on it. That kind of maintenance work is almost perfect agent work: deterministic feedback, clear pass/fail criteria, and a strong bias toward code that is simpler when the next functional requirement arrives.&lt;/p&gt;

&lt;p&gt;This matters because agents still tend to focus on the task directly in front of them. They do not reliably hold the full product plan or long-term architecture in mind. A clean, clear, well-tested codebase gives the agent guardrails. As the codebase grows, maintainable code is not only nicer for humans; it also makes future agent edits safer and less likely to drift away from the larger design. The bigger picture can stay in the human's mind, while the agent can be trusted with smaller, well-bounded changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deterministic tools should not be reinvented by an LLM
&lt;/h2&gt;

&lt;p&gt;Renaming a function is the simplest example. An LLM can search the codebase, edit every reference it finds, build, read errors, search again, and eventually get close. That is slow, token-heavy, and still easy to get subtly wrong.&lt;/p&gt;

&lt;p&gt;An IDE refactoring engine already knows how to do this. It has the PSI model, imports, overloads, references, usages, and project structure. For a task with a deterministic result, the agent should call the deterministic tool and spend its reasoning budget on higher-level design decisions.&lt;/p&gt;

&lt;p&gt;This becomes more interesting because agents are not limited by the same UI friction humans have. As a human, I sometimes ignore a long refactoring menu because reading it takes longer than doing the edit manually. An agent can inspect the available actions quickly, choose the right one, and let IntelliJ apply it. That is where coding agents can actually benefit more from a full IDE than humans do.&lt;/p&gt;

&lt;p&gt;AgentBridge exposes these IDE-native operations as tools: semantic navigation, usage search, refactoring, quick-fixes, inspections, test discovery, run configurations, debugging, Git operations, project structure, database browsing, and more. The goal is not to make the model pretend to be IntelliJ. The goal is to let IntelliJ do the things IntelliJ is already good at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting and linting should stay synchronized
&lt;/h2&gt;

&lt;p&gt;Formatting, linting, and import cleanup can be added to agents through hooks, skills, and instructions. Hooks are usually the best of those options because they call deterministic tools. Instructions that tell the model how to indent code are mostly wasted context.&lt;/p&gt;

&lt;p&gt;But hooks can still happen late in the flow. If a hook reformats a file after an edit, the agent may still hold the old version in context and make the next patch against stale text. That can cause avoidable conflicts or accidental rewrites.&lt;/p&gt;

&lt;p&gt;AgentBridge tries to keep this tighter. File writes go through IntelliJ's document model, auto-formatting and import optimization can run as part of the IDE-aware edit path, and the result is reported back to the agent immediately. Symbol-based edits go further by targeting methods, classes, and fields instead of fragile line ranges.&lt;/p&gt;

&lt;p&gt;The point is not that formatting is hard. The point is that the agent, the IDE buffer, and the user's editor should agree about what the file looks like as early as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The IDE has broader project context
&lt;/h2&gt;

&lt;p&gt;Over time I have also started using Git and database tools inside IntelliJ, not because the terminal versions are bad, but because the IDE already has connected context. It knows the project, open editors, VCS roots, run configurations, database connections, warnings, and generated files. Keeping those tools in one environment can reveal useful relationships that isolated terminal commands miss.&lt;/p&gt;

&lt;p&gt;AgentBridge follows the same idea. Git operations go through the IDE's VCS layer where possible. Test runs appear in the IDE test runner. Builds show up in the Build window. Database tools use configured IntelliJ data sources. The agent is not only editing files on disk; it is working inside the same project model the developer is using.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is still an experiment
&lt;/h2&gt;

&lt;p&gt;Agentic coding is still new. It is too early to say which interaction model will win. Lightweight editor wrappers, terminal harnesses, cloud agents, IDE plugins, and specialized MCP servers are all exploring useful pieces of the problem.&lt;/p&gt;

&lt;p&gt;AgentBridge is my argument for one particular direction: if a developer already benefits from a full IDE, an agent may benefit even more. The agent can offload deterministic operations to IDE APIs, react to feedback earlier, and spend more of its reasoning on the actual software change.&lt;/p&gt;

&lt;p&gt;That does not make the IDE-native approach universally better. It does make it worth trying, especially on projects where IntelliJ already understands a lot of the codebase and where fast feedback, safe refactoring, inspections, Git integration, and test tooling are part of the daily workflow.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Disclosure:&lt;br&gt;
This text is a collaboration between me, the &lt;a href="https://github.com/catatafishen/agentbridge" rel="noopener noreferrer"&gt;AgentBridge&lt;/a&gt; maintainer, and GitHub Copilot. I provided the core argument, examples, opinions, and direction. Copilot helped turn those notes into a structured essay, tighten the language, and add external references. The viewpoint is mine; AI helped with editing and drafting.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Turned IntelliJ Into a 90-Tool MCP Server for Coding Agents (and the Agent Built Most of It)</title>
      <dc:creator>Henrik Westergård</dc:creator>
      <pubDate>Wed, 25 Mar 2026 10:31:33 +0000</pubDate>
      <link>https://forem.com/catatafishen/i-turned-intellij-into-a-90-tool-mcp-server-for-coding-agents-and-the-agent-built-most-of-it-542g</link>
      <guid>https://forem.com/catatafishen/i-turned-intellij-into-a-90-tool-mcp-server-for-coding-agents-and-the-agent-built-most-of-it-542g</guid>
      <description>&lt;p&gt;I built a JetBrains plugin that gives coding agents real IDE capabilities: 90+ tools covering file editing through IntelliJ's Document API, code navigation via the PSI, git, build, tests, and immediate editor feedback including SonarLint findings after every edit. Most of the code was written by the agent using the plugin itself. Here is how that happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it started
&lt;/h2&gt;

&lt;p&gt;A few years ago I stepped away from active software development after changing jobs. Recently I got a GitHub Copilot license at work and decided to give agentic coding a real try. I had used Copilot before, but my experience with the JetBrains plugin had always been underwhelming. It works much better in VS Code, or at least it did historically. So instead of the plugin, I started running the Copilot CLI directly in the IntelliJ terminal. And honestly, that was already a revelation. Good enough that I wanted to push it further.&lt;/p&gt;

&lt;p&gt;Running an agent in a terminal inside your IDE quickly exposes three real problems though.&lt;/p&gt;

&lt;p&gt;File edits bypass the IDE. The agent writes directly to disk and IntelliJ does not know about it. No syntax highlighting, no auto-format, no undo history, and I had to manually refresh files constantly.&lt;/p&gt;

&lt;p&gt;The agent cannot use IDE intelligence. IntelliJ has incredibly fast code navigation: go to declaration, find usages, symbol search. The agent was spending turn after turn grepping through the project, reinventing what IntelliJ already does instantly.&lt;/p&gt;

&lt;p&gt;And the agent is completely blind to IDE feedback. If my code had a warning right there in the editor, the agent had no idea unless it happened to build. An obvious error might only be noticed at the very end of a turn, after several more questionable edits had been stacked on top. SonarLint findings were invisible entirely.&lt;/p&gt;

&lt;p&gt;These problems had an obvious solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building it
&lt;/h2&gt;

&lt;p&gt;I had never written a JetBrains plugin, never touched Kotlin, and had no practical experience with the MCP protocol. A few years ago I would never have taken this on, there were too many unknowns. But I had Copilot and wanted to see how far a coding assistant could carry me through genuinely unfamiliar territory.&lt;/p&gt;

&lt;p&gt;The answer was a working proof of concept in an afternoon.&lt;/p&gt;

&lt;p&gt;The code was a mess, of course. My first approach used a Go sidecar to bridge the Copilot SDK, so there were three languages in play simultaneously, Kotlin for the plugin UI, Java for the logic, and Go for the bridge. After discovering that ACP (Agent Client Protocol, Copilot's JSON-RPC 2.0 protocol over stdio) was a simpler path, I refactored everything and dropped the sidecar. Then I published to the JetBrains Marketplace.&lt;/p&gt;

&lt;p&gt;After posting on Reddit I got good feedback about allowing the plugin to run in pure MCP mode, so any external agent client could connect without the plugin managing the agent process itself. I also got requests to support more agents. Since I was already on ACP, adding more clients was straightforward.&lt;/p&gt;

&lt;p&gt;Almost everything in the project has been written by the agent, and once the plugin was stable enough, it started developing itself. It is the most complete vibe coding experience I have had. I have only prompted, reviewed and redirected. 99% of the source code is generated by LLMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;The plugin embeds a full MCP server inside IntelliJ. Tool calls go through IntelliJ's own APIs rather than raw disk, so edits come with undo history, auto-format and VCS tracking built in.&lt;/p&gt;

&lt;p&gt;In practice this means the agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;edit and read files through the Document API instead of writing directly to disk&lt;/li&gt;
&lt;li&gt;navigate code using IntelliJ's PSI (go to declaration, find references, symbol search) instead of text search&lt;/li&gt;
&lt;li&gt;see errors and warnings immediately after each edit, including SonarLint findings&lt;/li&gt;
&lt;li&gt;run tests and builds and get the results back in the tool response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IDE stays live while the agent works. Files the agent reads or edits open in the editor in real time and edits are highlighted. Git operations open the Git tool window. Test runs open the test runner. You can watch everything unfold without leaving IntelliJ.&lt;/p&gt;

&lt;p&gt;Supported agents are GitHub Copilot, JetBrains Junie, Amazon Kiro, OpenCode, Claude Code and OpenAI Codex, with switching between them from a dropdown. That is useful when you have multiple subscriptions since each typically includes some free usage.&lt;/p&gt;

&lt;p&gt;There is also an optional web-based chat UI served over HTTPS from localhost. It supports PWA so you can install it on your phone and follow along or respond to permission prompts when AFK.&lt;/p&gt;

&lt;h2&gt;
  
  
  The feedback loop is the point
&lt;/h2&gt;

&lt;p&gt;The feature I am most happy about is the immediate editor feedback after edits. When the agent adds code to an existing method and cyclomatic complexity spikes, SonarLint flags it the instant the edit lands. The agent sees it and refactors right there, rather than producing something that technically works but will cause pain later.&lt;/p&gt;

&lt;p&gt;This is also what makes the agent-builds-itself dynamic work well. Because every edit gets real IDE scrutiny in the same response, the generated code has to pass that bar before moving on. Over a long session this produces noticeably more maintainable code, and the agent builds a better mental model of the codebase as it goes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned about the protocols
&lt;/h2&gt;

&lt;p&gt;ACP and MCP are both fairly young and the gaps show when you run multiple agents through the same integration layer.&lt;/p&gt;

&lt;p&gt;The biggest challenge was tool call correlation. When an agent executes a tool, two separate events arrive: one over ACP carrying the UI representation, and one over MCP carrying the actual invocation. You need to match them up to show the right result in the UI.&lt;/p&gt;

&lt;p&gt;The approach I ended up with hashes the tool arguments using canonical JSON and SHA-256, using the first 8 characters as a correlation key. Both sides compute the same hash independently. There is also a FIFO fallback for synchronous tools where argument matching is not reliable.&lt;/p&gt;

&lt;p&gt;Claude Code CLI is the only agent that handles this at the protocol level, by embedding the ACP tool_use ID directly in the MCP _meta field. Every other agent does not send a correlation ID, so the hash fallback covers them. It would be nice if this was standardized, but the hash approach works well enough for now.&lt;/p&gt;

&lt;p&gt;Each agent also has its own quirks around error formats, tool result handling and what parts of the protocol they actually implement. Working through those has been the most educational part of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  License and privacy
&lt;/h2&gt;

&lt;p&gt;Since my original goal was a better agentic coding experience for colleagues in an enterprise environment, the license is Apache 2.0. There should be no question about whether it can be used at work.&lt;/p&gt;

&lt;p&gt;The plugin collects no data and has no telemetry. It only connects to IntelliJ's APIs and to whatever agent you configure. What the agents and JetBrains do on their end is outside my control, but the plugin itself is fully local.&lt;/p&gt;




&lt;p&gt;The plugin is &lt;a href="https://github.com/catatafishen/ide-agent-for-copilot" rel="noopener noreferrer"&gt;open source&lt;/a&gt; and available on the &lt;a href="https://plugins.jetbrains.com/plugin/30415-agentbridge" rel="noopener noreferrer"&gt;JetBrains Marketplace&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Here is the plugin Start-up Screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frveovbsoaj97x29dwayo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frveovbsoaj97x29dwayo.png" alt="Screenshot of init screen of plugin" width="539" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is what the chat looks like&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmahxhe2aduopq3615i8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmahxhe2aduopq3615i8e.png" alt="Screenshot of plugin" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>agents</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
