ide-integration-programmatic-messaging
Overview
Claude Code integrates with JetBrains IDEs (IntelliJ IDEA, WebStorm, PyCharm) and VS Code through dedicated plugins that bridge the IDE with the Claude Code CLI. While the IDE plugins provide context sharing and diff viewing, programmatic message submission to Claude Code is primarily achieved through headless mode and CLI automation rather than direct API calls.
Key Finding: The JetBrains/WebStorm plugin acts as a bridge to the Claude Code CLI terminal, not a standalone API. To programmatically trigger Claude Code from external tools, use headless mode with the -p flag or stdin piping.
IDE Integration
JetBrains Plugin (IntelliJ, WebStorm, PyCharm)
Installation:
- Install from JetBrains Marketplace
- Requires Claude Code CLI installed separately (
npm install -g @anthropic-ai/claude-code) - Restart IDE after installation
How It Works: The plugin coordinates with the Claude Code CLI running in your IDE terminal and displays proposed edits in the IDE diff viewer. It’s essentially terminal integration, not a separate API.
Key Features:
| Feature | Shortcut | Description |
|---|---|---|
| Quick Launch | Cmd+Esc (Mac)Ctrl+Esc (Win/Linux) | Opens Claude Code from editor |
| File Reference | Cmd+Option+K (Mac)Alt+Ctrl+K (Win/Linux) | Inserts @File#L1-99 references |
| Diff Viewing | Auto | Code changes shown in IDE diff viewer |
| Diagnostic Sharing | Auto | Shares lint errors, warnings, squigglies |
| Selection Context | Auto | Current tab/selection shared with Claude |
IDE Connection:
# Connect Claude Code to your JetBrains IDE from external terminalclaude /ideEnsure Claude Code runs from the same directory as your IDE project root for proper file access.
Limitations:
- Not a Deep Integration: Users report the integration feels “skin-deep” compared to VS Code
- CLI-Only Experience: JetBrains users rely on terminal interface, lacking the GUI experience VS Code offers
- Context Switching: Requires switching between IDE and terminal
- Beta Stability: Reports of IDE detection failures and plugin instability (as of Oct 2025)
- Last Update: WebStorm plugin last updated June 2025
VS Code Extension
VS Code has a GUI extension (Beta) providing a more integrated visual experience than the JetBrains CLI-only workflow. However, programmatic automation still relies on the CLI.
Programmatic Message Submission
Current State: No Direct API
Important: There is no direct API for programmatically sending text/messages to a running Claude Code session from external tools. The IDE plugins don’t expose programmatic submission methods.
Solutions:
- Headless Mode - Run Claude Code non-interactively with prompts
- Stdin Piping - Pipe data into Claude Code CLI
- CLI Automation - Script Claude Code with flags and options
1. Headless Mode (Non-Interactive)
Headless mode runs Claude Code programmatically for CI/CD, pre-commit hooks, build scripts, and automation.
Basic Usage:
claude -p "Your prompt here" \ --output-format stream-json \ --allowedTools "Bash,Read" \ --permission-mode acceptEditsKey Flags:
| Flag | Description |
|---|---|
-p, --print | Enable headless mode with prompt |
--output-format json | Output JSON for parsing |
--output-format stream-json | Stream JSON output |
--allowedTools | Whitelist specific tools |
--permission-mode | Set permission level |
--verbose | Verbose output for debugging |
Multi-Turn Conversations:
# Continue most recent sessionclaude --continue "Now refactor for performance"
# Resume specific session by IDclaude --resume 550e8400-e29b-41d4-a716-446655440000 "Update tests"Use Cases:
- CI/CD pipelines
- GitHub Actions automation
- Pre-commit hooks
- Build script integration
- Automated code review
Limitation: Headless mode does not persist between sessions. Each invocation starts fresh unless using --continue or --resume.
2. Stdin Piping
Claude Code supports piping data via stdin for single-turn or multi-turn conversations.
Basic Piping:
# Pipe file contentcat foo.txt | claude -p "Explain this code"
# Pipe command outputgit diff main | claude -p "Review these changes"
# Redirect file inputclaude -p < prompt.txtPipeline Integration:
# Process output in pipelinecat build-error.txt | claude -p 'Explain root cause' > output.txt
# JSON output for structured parsingclaude -p "<prompt>" --output-format json | your_commandMulti-Turn Stdin (Advanced):
Headless mode supports a stream of messages via stdin where each message represents a user turn. This allows multiple conversation turns without re-launching the claude binary.
Feature Request (Not Yet Implemented): GitHub Issue #6009 proposes piping stdin to pre-populate the interactive TUI prompt:
# Proposed (not yet available)git diff main | claude # Would launch TUI with diff pre-populatedCurrently, piping requires the -p flag for headless mode. Without -p, piped stdin is ignored in interactive mode.
3. CLI Automation Examples
GitHub Actions Integration:
claude -p "Analyze this GitHub Issue and add labels" \ --allowedTools "Read,Bash(gh:*)"Pre-Commit Hook:
#!/bin/bashgit diff --cached | claude -p "Review staged changes for issues" \ --output-format json \ | jq -r '.result'Custom Script Automation:
#!/bin/bash# Automated code reviewREVIEW=$(claude -p "Review $(cat changed_files.txt)" --output-format json)echo "$REVIEW" | jq -r '.suggestions[]' > review.mdIDE-Specific Context Management
CLAUDE.md Auto-Loading
Create CLAUDE.md in your project root to auto-load context into Claude Code sessions:
# Project Context
## Branch Naming- feature/name- bugfix/name
## Environment Setup- Node.js 18+- Bun for package management
## Known Quirks- Use bun instead of npmUse /init to bootstrap a CLAUDE.md with sensible sections.
Slash Commands for Context
/add-dir path/to/folder # Include subdirectory in context/ide # Connect to JetBrains IDEDiagnostic Sharing (JetBrains)
The JetBrains plugin automatically shares IDE diagnostics (lint errors, warnings, squigglies) with Claude in real-time, providing more context for accurate fixes.
Architecture: How IDE Integration Works
WebSocket MCP Protocol
The plugin uses JSON-RPC 2.0 over WebSocket implementing the Model Context Protocol (MCP):
┌─────────────────────────────────────────┐│ JetBrains IDE (WebStorm, IntelliJ) ││ ││ ┌────────────────────────────────┐ ││ │ Claude Code Plugin (Beta) │ ││ │ WebSocket Server (MCP) │ ││ │ Port: random 10000-65535 │ ││ └──────────┬─────────────────────┘ ││ │ ││ │ Lock file: ~/.claude/ide/[port].lock│ │ ││ ┌──────────▼─────────────────────┐ ││ │ Claude Code CLI (client) │ ││ │ - Discovers via lock file │ ││ │ - Connects to WebSocket │ ││ └────────────────────────────────┘ │└─────────────────────────────────────────┘Lock File Discovery
Lock File Format (~/.claude/ide/[port].lock):
{ "pid": 12345, "workspaceFolders": ["/home/uptown/Projects/research"], "ideName": "WebStorm", "transport": "ws", "authToken": "550e8400-e29b-41d4-a716-446655440000"}Connection Flow:
- Plugin starts WebSocket server on random port (10000-65535)
- Writes lock file with port + auth token (UUID v4)
- Claude CLI scans
~/.claude/ide/for lock files - Connects with header:
x-claude-code-ide-authorization: [authToken]
Ctrl+Alt+C Flow (File Reference Injection)
When you select text and press Ctrl+Alt+C (or Cmd+Option+K on Mac):
1. WebStorm captures selection: - File: /home/uptown/Projects/research/.env - Lines: 2-2 - Content: (selected text)
2. Plugin sends via WebSocket (JSON-RPC 2.0): { "jsonrpc": "2.0", "method": "at_mentioned", "params": { "file": "/home/uptown/Projects/research/.env", "startLine": 2, "endLine": 2, "selection": "VOYAGE_API_KEY=..." } }
3. Claude CLI receives message via WebSocket
4. Injects into TUI prompt buffer: @.env#L2Available MCP Tools (Claude → IDE)
| Tool | Description |
|---|---|
getCurrentSelection | Get active editor selection |
getLatestSelection | Most recent selection (50ms debounce) |
getDiagnostics | Fetch lint errors, warnings, syntax errors |
getOpenEditors | List all open tabs with metadata |
getWorkspaceFolders | Project root paths |
openFile | Open file with optional line selection |
openDiff | Show diff (blocking, waits for user approval) |
saveDocument | Save file changes |
checkDocumentDirty | Check for unsaved changes |
close_tab | Close editor tabs |
closeAllDiffTabs | Clear diff views |
executeCode | Run code in IDE |
IDE → Claude Events
| Event | Trigger | Description |
|---|---|---|
selection_changed | Automatic (50ms debounce) | Fires when text selection updates |
at_mentioned | Ctrl+Alt+C / Cmd+Option+K | Explicit file reference injection |
Diagnostic Sharing Flow
IDE Language Servers (ESLint, TypeScript, etc.) ↓Plugin aggregates diagnostics via IDE API ↓Claude calls getDiagnostics tool via WebSocket ↓Plugin returns errors/warnings as JSON ↓Claude receives full IDE state for contextKey Insight: The plugin is a WebSocket MCP server. Claude CLI is the client that discovers it via lock files. To programmatically inject text, you can connect to the same WebSocket and send at_mentioned events.
Programmatic Trigger from IDE: Possible Approaches
Option 1: Custom IDE Action Executing CLI
Create a WebStorm/IntelliJ action that:
- Captures current selection or file
- Shells out to
claude -pwith the content - Displays result back in IDE
Example Pseudocode (IntelliJ Plugin):
// Custom action to send selection to Claude Codeval selection = editor.selectionModel.selectedTextval result = Runtime.getRuntime() .exec(arrayOf("claude", "-p", "Explain: $selection", "--output-format", "json")) .inputStream.bufferedReader().readText()
// Parse and display resultOption 2: External Script + Hotkey
Use a global hotkey tool (e.g., Hammerspoon on Mac, AutoHotkey on Windows) to:
- Capture IDE clipboard/selection
- Run
claude -pwith content - Paste result back
Example (Hammerspoon):
hs.hotkey.bind({"cmd", "alt"}, "C", function() local selection = hs.pasteboard.getContents() local result = hs.execute("echo '"..selection.."' | claude -p 'Explain this'") hs.pasteboard.setContents(result) hs.alert.show("Claude result copied to clipboard")end)Option 3: Wait for Feature Request
Track GitHub Issue #6009 for native support to pipe stdin into the interactive TUI without needing -p flag.
Security Considerations
CVE-2025-52882: WebSocket Authentication Bypass (Patched)
Earlier versions had unauthenticated WebSocket servers, allowing malicious websites to connect via browser’s WebSocket (not bound by same-origin policy).
Impact: Attackers could read files, get selection events, list open files, and access syntax errors.
Fix: UUID v4 authentication tokens in lock files (patched in v1.0.24+). The auth token must be included in the x-claude-code-ide-authorization header.
Best Practice: Always run the latest Claude Code version.
Known Issues & Limitations
| Issue | Description | Status |
|---|---|---|
| No Direct API | IDE plugins don’t expose programmatic submission API | Current Architecture |
| Headless Non-Persistent | Each -p invocation starts fresh unless using --continue | Design Limitation |
| Interactive Stdin | Piping stdin doesn’t pre-populate interactive TUI prompt | Feature Request #6009 |
| JetBrains Stability | Plugin detection failures, requires IDE restarts | Beta (Oct 2025) |
| CLI Error (Recent) | claude -p fails with 400 error in some versions | Bug #11678 |
Sources
IDE Integration
- JetBrains IDEs - Claude Code Docs
- Claude Code [Beta] - IntelliJ IDEs Plugin | Marketplace
- Claude Code: Part 7 - IDE Integration with VS Code and JetBrains
- Integrating Claude Code Plugin with VSCode & JetBrains: Ultimate Guide
- Introducing Claude Agent in JetBrains IDEs | The JetBrains AI Blog
Programmatic/CLI Automation
- Headless mode - Claude Code Docs
- CLI reference - Claude Code Docs
- Feature Request: Allow piping input to pre-populate the interactive session prompt · Issue #6009
- A Comprehensive Guide to the Claude Code SDK
- Integrating Claude Code with GitHub Actions
- Claude Code and Bash Scripts
- Non Interactive Mode · ruvnet/claude-flow Wiki
- ClaudeCode Tutorial Center - Complete Claude Code AI Programming Assistant Guide
WebSocket MCP Protocol
- coder/claudecode.nvim - GitHub - Neovim implementation with full protocol documentation
- coder/claudecode.nvim PROTOCOL.md - WebSocket MCP protocol specification
- CVE-2025-52882: WebSocket authentication bypass | Datadog Security Labs - Security analysis confirming architecture
- emilianbold/claude-code-netbeans - NetBeans implementation with MCP server
- mahowa/claude-jetbrains - Community JetBrains plugin implementation