hechtcarmel/jetbrains-index-mcp-plugin

hechtcarmel/jetbrains-index-mcp-plugin

β˜• 🏠 - A JetBrains IDE plugin that exposes an MCP server, enabling AI coding assistants to leverage the IDE's indexing and refactoring capabilities (rename, safe delete, find references, call hierarchy, type hierarchy, diagnostics and more).

CLAUDE.md

IDE Index MCP Server - Development Guide

An IntelliJ Platform plugin that exposes an MCP (Model Context Protocol) server, enabling coding agents to leverage the IDE's powerful indexing and refactoring capabilities.

Works with JetBrains IDEs: IntelliJ IDEA, PyCharm, WebStorm, GoLand, PhpStorm, RubyMine, CLion, RustRover, DataGrip, and Android Studio.

Project Overview

Goal

Create an MCP server within an IntelliJ plugin that allows AI coding assistants to:

  • Perform refactoring operations (rename, extract, move, etc.)
  • Query type hierarchy and call hierarchy
  • Access code navigation features (find usages, find definition)
  • Leverage IDE indexes for fast code search and analysis
  • Use code completion and inspection APIs

Technology Stack

  • Language: Kotlin (JVM 21)
  • Build System: Gradle 9.0 with Kotlin DSL
  • IDE Platform: IntelliJ IDEA 2025.1+ (platformType = IC)
  • HTTP Server: Ktor CIO 2.3.12 (embedded, configurable port)
  • Protocol: Model Context Protocol (MCP) 2025-03-26

Key Documentation

IntelliJ Platform SDK

Model Context Protocol (MCP)

Project Structure

src/
β”œβ”€β”€ main/
β”‚   β”œβ”€β”€ kotlin/com/github/hechtcarmel/jetbrainsindexmcpplugin/
β”‚   β”‚   β”œβ”€β”€ MyBundle.kt                 # Resource bundle accessor
β”‚   β”‚   β”œβ”€β”€ handlers/                   # Language-specific handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ LanguageHandler.kt      # Handler interfaces & data classes
β”‚   β”‚   β”‚   β”œβ”€β”€ LanguageHandlerRegistry.kt # Data-driven handler registry
β”‚   β”‚   β”‚   β”œβ”€β”€ OptimizedSymbolSearch.kt # Symbol search using platform APIs
β”‚   β”‚   β”‚   β”œβ”€β”€ java/JavaHandlers.kt    # Java/Kotlin handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ python/PythonHandlers.kt # Python handlers (reflection)
β”‚   β”‚   β”‚   β”œβ”€β”€ javascript/JavaScriptHandlers.kt # JS/TS handlers (reflection)
β”‚   β”‚   β”‚   β”œβ”€β”€ go/GoHandlers.kt        # Go handlers (reflection)
β”‚   β”‚   β”‚   β”œβ”€β”€ php/PhpHandlers.kt      # PHP handlers (reflection)
β”‚   β”‚   β”‚   └── rust/RustHandlers.kt    # Rust handlers (reflection)
β”‚   β”‚   β”œβ”€β”€ server/                     # MCP server infrastructure
β”‚   β”‚   β”‚   β”œβ”€β”€ McpServerService.kt     # App-level service managing server lifecycle
β”‚   β”‚   β”‚   β”œβ”€β”€ JsonRpcHandler.kt       # JSON-RPC 2.0 request routing
β”‚   β”‚   β”‚   β”œβ”€β”€ ProjectResolver.kt      # Multi-project resolution with workspace support
β”‚   β”‚   β”‚   β”œβ”€β”€ models/                 # Protocol models (JsonRpc, MCP)
β”‚   β”‚   β”‚   └── transport/              # HTTP+SSE transport layer
β”‚   β”‚   β”‚       β”œβ”€β”€ KtorMcpServer.kt    # Embedded Ktor CIO server
β”‚   β”‚   β”‚       β”œβ”€β”€ KtorSseSessionManager.kt # SSE session management
β”‚   β”‚   β”œβ”€β”€ startup/                    # Startup activities
β”‚   β”‚   β”œβ”€β”€ tools/                      # MCP tool implementations
β”‚   β”‚   β”‚   β”œβ”€β”€ McpTool.kt             # Tool interface
β”‚   β”‚   β”‚   β”œβ”€β”€ AbstractMcpTool.kt     # Base class (PSI sync, threading, helpers)
β”‚   β”‚   β”‚   β”œβ”€β”€ ToolRegistry.kt        # Data-driven tool registry
β”‚   β”‚   β”‚   β”œβ”€β”€ schema/                # Tool schema utilities
β”‚   β”‚   β”‚   β”‚   └── SchemaBuilder.kt   # Fluent builder for input schemas
β”‚   β”‚   β”‚   β”œβ”€β”€ editor/                # Editor interaction tools
β”‚   β”‚   β”‚   β”œβ”€β”€ navigation/            # Navigation tools (multi-language)
β”‚   β”‚   β”‚   β”œβ”€β”€ intelligence/          # Code analysis tools
β”‚   β”‚   β”‚   β”œβ”€β”€ project/               # Project status tools
β”‚   β”‚   β”‚   └── refactoring/           # Refactoring tools
β”‚   β”‚   β”œβ”€β”€ util/                      # Utilities
β”‚   β”‚   β”‚   β”œβ”€β”€ PluginDetector.kt      # Generic plugin availability detector
β”‚   β”‚   β”‚   β”œβ”€β”€ PluginDetectors.kt     # Registry of all language detectors
β”‚   β”‚   β”‚   β”œβ”€β”€ ClassResolver.kt       # Class lookup by FQN (Java, PHP)
β”‚   β”‚   β”‚   β”œβ”€β”€ ProjectUtils.kt        # Project/workspace helpers
β”‚   β”‚   β”‚   β”œβ”€β”€ PsiUtils.kt            # PSI navigation helpers
β”‚   β”‚   β”‚   └── ThreadingUtils.kt      # Threading utilities
β”‚   β”‚   └── ui/                        # Tool window UI
β”‚   └── resources/
β”‚       β”œβ”€β”€ META-INF/
β”‚       β”‚   β”œβ”€β”€ plugin.xml              # Plugin configuration
β”‚       β”‚   └── *-features.xml          # Optional language-specific extensions
β”‚       └── messages/MyBundle.properties # i18n messages
└── test/
    β”œβ”€β”€ kotlin/                         # Test sources
    └── testData/                       # Test fixtures

Architecture Concepts

IntelliJ Platform Key Components

  1. PSI (Program Structure Interface)

    • Core abstraction for parsing and representing code structure
    • PsiFile, PsiElement, PsiClass, PsiMethod, etc.
    • PsiNamedElement for elements that can be renamed/referenced
  2. Indexes

    • DumbService - query if IDE is in dumb mode (indexing) vs smart mode
    • File-based indexes for fast lookups
    • PSI stubs for lightweight syntax trees
  3. Refactoring APIs

    • RenameHandler - custom rename UI/workflow
    • PsiNamedElement.setName() - rename element
    • PsiReference.handleElementRename() - update references
  4. Services

    • Application-level services (singleton across IDE)
    • Project-level services (one per open project)

Workspace / Multi-Module Project Support

The plugin supports workspace projects where a single IDE window contains multiple sub-projects represented as modules with separate content roots:

  • Project resolution (ProjectResolver.resolve): Checks exact basePath β†’ module content roots β†’ subdirectory match
  • File resolution (AbstractMcpTool.resolveFile): Tries basePath, then module content roots
  • Relative path computation (ProjectUtils.getRelativePath): Strips the matching content root prefix
  • VFS/PSI sync (AbstractMcpTool.ensurePsiUpToDate): Refreshes all content roots, not just basePath
  • Error responses: available_projects detail is configurable. Expanded mode includes workspace sub-projects with their workspace parent name; compact mode returns only top-level project roots.

Key utility: ProjectUtils.getModuleContentRoots(project) returns all module content root paths.

MCP Server Architecture

MCP servers expose:

  • Tools - Operations that can be invoked (e.g., rename_symbol, find_usages)
  • Prompts - Pre-defined interaction templates (optional)

Server Infrastructure:

  • Custom embedded Ktor CIO HTTP server (not IntelliJ's built-in server)
  • Configurable port with IDE-specific defaults (e.g., IntelliJ: 29170, PyCharm: 29172) via Settings β†’ Index MCP Server β†’ Server Port
  • Binds to 127.0.0.1 only (localhost) for security
  • Single server instance across all open projects
  • Auto-restart on port change

Key Server Classes:

  • McpServerService - Application-level service managing server lifecycle
  • KtorMcpServer - Embedded Ktor CIO server with CORS support
  • KtorSseSessionManager - SSE session management using Kotlin channels
  • JsonRpcHandler - JSON-RPC 2.0 request processing

Transport: This plugin supports two transports with JSON-RPC 2.0:

Streamable HTTP (Primary, MCP 2025-03-26):

  • POST /index-mcp/streamable-http β†’ Stateless JSON-RPC requests/responses
  • GET /index-mcp/streamable-http β†’ 405 Method Not Allowed
  • DELETE /index-mcp/streamable-http β†’ 405 Method Not Allowed

Legacy SSE (MCP 2024-11-05):

  • GET /index-mcp/sse β†’ Opens SSE stream, sends endpoint event with POST URL
  • POST /index-mcp β†’ JSON-RPC requests/responses

Client Configuration (Cursor, Claude Desktop, etc.):

{
  "mcpServers": {
    "intellij-index": {
      "url": "http://127.0.0.1:29170/index-mcp/streamable-http"
    }
  }
}

Note: Server name and port are IDE-specific. Use the "Install on Coding Agents" button for automatic configuration.

Port Configuration: Settings β†’ Tools β†’ Index MCP Server β†’ Server Port (IDE-specific defaults, range: 1024-65535)

IDE-Specific Defaults:

IDE Server Name Default Port
IntelliJ IDEA intellij-index 29170
Android Studio android-studio-index 29171
PyCharm pycharm-index 29172
WebStorm webstorm-index 29173
GoLand goland-index 29174
PhpStorm phpstorm-index 29175
RubyMine rubymine-index 29176
CLion clion-index 29177
RustRover rustrover-index 29178
DataGrip datagrip-index 29179
Aqua aqua-index 29180
DataSpell dataspell-index 29181
Rider rider-index 29182

Development Guidelines

Kotlin Standards

  • Use Kotlin idioms (data classes, extension functions, coroutines where appropriate)
  • Leverage null safety features
  • Use @RequiresBackgroundThread / @RequiresReadLock annotations where needed

IntelliJ Platform Best Practices

  • Always check DumbService.isDumb() before accessing indexes
  • Use ReadAction / WriteAction for PSI modifications
  • Register extensions in plugin.xml, not programmatically
  • Use ApplicationManager.getApplication().invokeLater() for UI updates
  • Handle threading correctly (read actions on background threads, write actions on EDT)

PSI-Document Synchronization

The IntelliJ Platform maintains separate Document (text) and PSI (parsed structure) layers. When files are modified externally (e.g., by AI coding tools), PSI may not immediately reflect the changes. This can cause search APIs to miss references in newly created files.

Solution: AbstractMcpTool automatically refreshes the VFS and commits documents before executing any tool. This ensures PSI is synchronized with external file changes.

User Setting: "Sync external file changes before operations" (Settings β†’ MCP Server)

  • Disabled (default): Best performance, suitable for most use cases
  • Enabled: WARNING - SIGNIFICANT PERFORMANCE IMPACT. Use only when rename/find-usages misses references in files just created externally. Each operation will take seconds instead of milliseconds on large repos.

For tool developers:

  • Extend AbstractMcpTool and implement doExecute() (not execute())
  • PSI synchronization happens automatically before doExecute() is called
  • To opt-out (for tools that don't use PSI), override:
    override val requiresPsiSync: Boolean = false
    

Code Style

  • Follow Kotlin coding conventions
  • Use meaningful variable names
  • Keep functions small and focused
  • Extract reusable logic to utility classes

Tool Schema Guidelines

All tool input schemas MUST use SchemaBuilder (in tools/schema/SchemaBuilder.kt). This eliminates boilerplate and ensures consistency:

// βœ“ Use SchemaBuilder for all tool schemas
override val inputSchema = SchemaBuilder.tool()
    .projectPath()
    .file()
    .lineAndColumn()
    .intProperty("maxResults", "Maximum results to return. Default: 100, max: 500.")
    .build()

// For enum parameters:
.enumProperty("matchMode", "How to match the query.", listOf("substring", "prefix", "exact"))

// For complex properties that don't fit the builder, use the escape hatch:
.property("target_type", buildJsonObject { /* custom schema */ })

Building and Running

# Build the plugin
./gradlew build

# Run IDE with plugin installed
./gradlew runIde

# Run tests
./gradlew test

# Run plugin verification
./gradlew runPluginVerifier

Run Configurations (in .run/)

  • Run Plugin - Launch IDE with plugin for manual testing
  • Run Tests - Execute unit tests
  • Run Verifications - Run compatibility checks

Plugin Configuration

Key files:

  • gradle.properties - Plugin metadata (version, IDs, platform version)
  • plugin.xml - Extension points and dependencies
  • build.gradle.kts - Build configuration

Adding Dependencies

  1. Add to gradle/libs.versions.toml for version catalog
  2. Reference in build.gradle.kts using libs.xxx syntax

Adding Extension Points

Register in plugin.xml:

<extensions defaultExtensionNs="com.intellij">
    <your.extension implementation="com.your.ImplementationClass"/>
</extensions>

Testing

Test Architecture

Tests are split into two categories to optimize execution time:

  1. Unit Tests (*UnitTest.kt) - Extend junit.framework.TestCase

    • Fast, no IntelliJ Platform initialization required
    • Use for: serialization, schema validation, data classes, registries, pure logic
    • Run with: ./gradlew test --tests "*UnitTest*"
  2. Platform Tests (*Test.kt) - Extend BasePlatformTestCase

    • Slower, requires full IntelliJ Platform with indexing
    • Use for: tests needing project, PSI operations, tool execution, resource reads
    • Run with: ./gradlew test --tests "*Test" --tests "!*UnitTest*"

Test File Conventions

Test Class Base Class Purpose
McpPluginUnitTest TestCase JSON-RPC serialization, error codes, registry
McpPluginTest BasePlatformTestCase Platform availability
ToolsUnitTest TestCase Tool schemas, registry, definitions
ToolsTest BasePlatformTestCase Tool execution with project
JsonRpcHandlerUnitTest TestCase JSON-RPC protocol, error handling
JsonRpcHandlerTest BasePlatformTestCase Tool calls requiring project
CommandHistoryUnitTest TestCase Data classes, filters
CommandHistoryServiceTest BasePlatformTestCase Service with project

When to Use Each Base Class

Use TestCase (unit test) when:

  • Testing serialization/deserialization
  • Validating schemas and definitions
  • Testing data classes and their properties
  • Testing registries without executing tools
  • No project instance is needed

Use BasePlatformTestCase (platform test) when:

  • Test needs project instance
  • Test executes tools against a project
  • Test uses project-level services (e.g., CommandHistoryService)
  • Test needs PSI or index access

Running Tests

# Run all tests
./gradlew test

# Run only fast unit tests (recommended for quick feedback)
./gradlew test --tests "*UnitTest*"

# Run only platform tests
./gradlew test --tests "*Test" --tests "!*UnitTest*"

# Run specific test class
./gradlew test --tests "McpPluginUnitTest"

Test Data

  • Place test fixtures in src/test/testData/
  • Test both smart mode and dumb mode scenarios for platform tests

MCP Implementation Notes

Implemented Tools

Tools are organized by IDE availability.

Universal Tools (All JetBrains IDEs):

  • ide_find_references - Find all usages of a symbol. Supports language+symbol as alternative to file+line+column.
  • ide_find_definition - Find symbol definition location. Supports language+symbol as alternative to file+line+column.
  • ide_find_class - Search for classes/interfaces by name with camelCase/substring/wildcard matching
  • ide_find_file - Search for files by name using IDE's file index
  • ide_search_text - Text search using IDE's pre-built word index with context filtering
  • ide_read_file - Read file content by path or qualified name, including library/jar sources (disabled by default)
  • ide_diagnostics - Unified diagnostics tool: per-file code analysis (errors, warnings, intentions), build output from last build, and test results from open test run tabs. Supports includeBuildErrors, includeTestResults, severity filter, testResultFilter, maxBuildErrors, maxTestResults. The file parameter is now optional.
  • ide_index_status - Check indexing status (dumb/smart mode)
  • ide_sync_files - Force sync IDE's virtual file system and PSI cache with external file changes
  • ide_build_project - Build project using IDE's build system (JPS, Gradle, Maven). Returns structured errors/warnings with file locations when available (null counts = no messages captured, not 0). Uses CompilationStatusListener for JPS builds and BuildProgressListener for Gradle/Maven builds. Supports workspace sub-project targeting via project_path. (disabled by default)
  • ide_refactor_rename - Rename a symbol or file across the project with automatic related element renaming (getters/setters, overriding methods). Fully headless, works for ALL languages. Two modes: symbol rename (file + line + column + newName) and file rename (file + newName, omit line/column). File rename mode works for all file types including binary files (images, etc.) and is especially useful for Android resource files where it updates all XML references. Supports relatedRenamingStrategy parameter to control automatic related renames: "all" (default), "none", "accessors_and_tests", or "ask".
  • ide_move_file - Move a file to a new directory using the IDE's refactoring engine. Automatically updates all references, imports, and package declarations across the project. Supports automatic directory creation and optional reference update toggle.
  • ide_reformat_code - Reformat code using project code style (.editorconfig, IDE settings). Supports optional import optimization and code rearrangement. (disabled by default)
  • ide_optimize_imports - Optimize imports (remove unused, organize) without reformatting code. Equivalent to IDE's Ctrl+Alt+O. (disabled by default)
  • ide_get_active_file - Get the currently active file(s) in the editor (disabled by default)
  • ide_open_file - Open a file in the editor with optional line/column navigation (disabled by default)

Extended Navigation Tools (Language-Aware):

These activate based on available language plugins (Java, Python, JavaScript/TypeScript, Go, PHP, Rust):

  • ide_type_hierarchy - Get type hierarchy for a class (Java, Kotlin, Python, JS/TS, Go, PHP, Rust)
  • ide_call_hierarchy - Get call hierarchy for a method (Java, Kotlin, Python, JS/TS, Go, PHP, Rust). Supports language+symbol as alternative to file+line+column.
  • ide_find_implementations - Find implementations of interface/method (Java, Kotlin, Python, JS/TS, PHP, Rust β€” not Go). Supports language+symbol as alternative to file+line+column.
  • ide_find_symbol - Search for symbols (classes, methods, fields) by name with fuzzy/camelCase matching (disabled by default)
  • ide_find_super_methods - Find methods that a given method overrides/implements (Java, Kotlin, Python, JS/TS, PHP β€” not Go, Rust). Supports language+symbol as alternative to file+line+column.
  • ide_file_structure - Get hierarchical file structure similar to IDE's Structure view (Java, Kotlin, Python, JS/TS) (disabled by default)

Java/Kotlin-Only Refactoring Tools:

  • ide_refactor_safe_delete - Safely delete element (requires Java plugin)

Kotlin Conversion Tools:

  • ide_convert_java_to_kotlin - Convert Java files to Kotlin using IntelliJ's built-in J2K converter. Supports full file conversion with automatic formatting and import optimization. Handles classes, interfaces, methods, generics, Java 8+ features (lambdas, streams). Returns list of created .kt files and conversion warnings. Requires both Java and Kotlin plugins. (disabled by default)

Multi-Language Architecture

The plugin uses a language handler pattern for multi-IDE support:

Core Components:

  • LanguageHandler<T> - Base interface for language-specific handlers
  • LanguageHandlerRegistry - Central registry managing all language handlers
  • PluginDetectors - Central registry of language plugin availability detectors (runs once at startup)

Language Handlers (in handlers/ package):

  • handlers/java/JavaHandlers.kt - Direct PSI access for Java/Kotlin
  • handlers/python/PythonHandlers.kt - Reflection-based Python PSI access
  • handlers/javascript/JavaScriptHandlers.kt - Reflection-based JS/TS PSI access
  • handlers/go/GoHandlers.kt - Reflection-based Go PSI access
  • handlers/php/PhpHandlers.kt - Reflection-based PHP PSI access
  • handlers/rust/RustHandlers.kt - Reflection-based Rust PSI access

Handler Types:

  • TypeHierarchyHandler - Type hierarchy lookup
  • ImplementationsHandler - Find implementations
  • CallHierarchyHandler - Call hierarchy analysis
  • SymbolSearchHandler - Symbol search by name
  • SymbolReferenceHandler - Resolve fully qualified symbol references (e.g., com.example.MyClass#method(String)) to PSI elements
  • SuperMethodsHandler - Method override hierarchy

Registration Flow:

  1. LanguageHandlerRegistry.registerHandlers() - Registers handlers for available language plugins
  2. ToolRegistry.registerUniversalTools() - Registers universal tools including ide_refactor_rename, ide_sync_files
  3. ToolRegistry.registerLanguageNavigationTools() - Registers tools if any language handlers available
  4. ToolRegistry.registerJavaRefactoringTools() - Registers ide_refactor_safe_delete if Java plugin available

Reflection Pattern: Python, JavaScript, Go, PHP, and Rust handlers use reflection to avoid compile-time dependencies on language-specific plugins. This prevents NoClassDefFoundError in IDEs without those plugins.

Optimized Symbol Search

Symbol search across all languages uses OptimizedSymbolSearch (in handlers/OptimizedSymbolSearch.kt):

  • Leverages IntelliJ's "Go to Symbol" APIs (ChooseByNameContributor)
  • Uses MinusculeMatcher for CamelCase, substring, and typo-tolerant matching
  • Supports language filtering (e.g., languageFilter = setOf("Java", "Kotlin"))

Pagination

The plugin supports cursor-based pagination for search tools that return flat result lists: ide_find_references, ide_search_text, ide_find_class, ide_find_file, ide_find_symbol, ide_find_implementations.

Key components:

  • PaginationService (server/PaginationService.kt): Application-level light service managing cursor cache
  • Cursor tokens are opaque, immutable, base64url-encoded strings containing {entryId}:{offset}:{pageSize}
  • Same cursor token always returns the same page (idempotent, safe for retries)
  • Each response includes nextCursor for the next page

Cache lifecycle:

  • Over-collection: tools collect 500 results internally, serve in configurable page sizes (default varies per tool)
  • Inactivity-based TTL: 10 minutes of idle time before cursor expires
  • LRU eviction: max 20 active cursors
  • Max 5,000 cached results per cursor; beyond this, hasMore returns false
  • Staleness detection via PsiModificationTracker β€” stale: true in response if PSI changed

Tool integration pattern:

  1. Check for cursor parameter β†’ serve from cache via getPageFromCache()
  2. Fresh search β†’ collect results, create cursor via PaginationService.createCursor(), serve first page
  3. searchExtender lambda enables lazy cache extension when pages are exhausted
  4. Each tool has a buildPaginatedResult() helper mapping GetPageResult to its own result model

Schema: All parameters are optional in the schema (no required array) because the Anthropic API does not support anyOf/oneOf at the top level. Validation is done at runtime β€” if cursor is absent, the tool checks for its required search params and returns an error if missing.

Backward compatibility: Old limit/maxResults parameters work as aliases for pageSize. Legacy cursors (without embedded pageSize) are still decodable but require an explicit pageSize parameter.

Search Collection Pattern (Processor)

All search operations use the Processor pattern for efficient streaming and early termination:

// βœ— Inefficient: loads all results into memory
val results = SomeSearch.search(element).findAll().take(100)

// βœ“ Efficient: streams results with early termination
val results = mutableListOf<Result>()
SomeSearch.search(element).forEach(Processor { item ->
    results.add(convertToResult(item))
    results.size < 100  // Return false to stop iteration
})

Useful IntelliJ Platform Classes

// PSI Navigation
PsiTreeUtil           // Tree traversal utilities
PsiUtilCore          // Core PSI utilities
ReferencesSearch     // Find references to element

// Refactoring
RefactoringFactory   // Create refactoring instances
RenameProcessor      // Rename refactoring
RefactoringBundle    // Refactoring messages

// Indexes
DumbService          // Check index status
FileBasedIndex       // Access file indexes
StubIndex            // Access stub indexes

// Project Structure
ProjectRootManager   // Project roots
ModuleManager        // Module access
VirtualFileManager   // Virtual file system

Troubleshooting

Common Issues

  1. IndexNotReadyException - Accessing indexes in dumb mode

    • Solution: Use DumbService.getInstance(project).runWhenSmart { ... }
  2. WriteAction required - Modifying PSI without write lock

    • Solution: Wrap in WriteCommandAction.runWriteCommandAction(project) { ... }
  3. Must be called from EDT - UI operations on background thread

    • Solution: Use ApplicationManager.getApplication().invokeLater { ... }
  4. Search misses newly created files - PSI not synchronized with document

    • Cause: External tools modified files but PSI tree hasn't been updated
    • Solution: Enable "Sync external file changes" in Settings β†’ MCP Server (WARNING: significant performance impact)
    • For custom code: PsiDocumentManager.getInstance(project).commitAllDocuments()

Contributing / PR Checklist

Every PR must include:

  1. Version bump β€” Update pluginVersion in gradle.properties following SemVer:
    • Patch (3.x.Y): Bug fixes, internal refactoring with no behavior change
    • Minor (3.Y.0): New features, new tools, protocol improvements
    • Major (Y.0.0): Breaking changes to tool schemas, transport, or client configuration
  2. CHANGELOG.md update β€” Add an entry under ## [Unreleased] following Keep a Changelog format. Use sections: Added, Changed, Fixed, Removed, Breaking
  3. Follow existing code patterns and use SchemaBuilder for new tool schemas
  4. Add tests for new functionality
  5. Update this documentation (CLAUDE.md) for any structural or architectural changes
  6. Run ./gradlew test to verify all tests pass (do NOT run platform tests yourself)

Template Source: JetBrains IntelliJ Platform Plugin Template

  • Never run platform tests on your own
README.md

IDE Index MCP Server

Build Version Downloads

A JetBrains IDE plugin that exposes an MCP (Model Context Protocol) server, enabling AI coding assistants like Claude, Codex, Cursor, and Windsurf to leverage the IDE's powerful indexing and refactoring capabilities.

Fully tested: IntelliJ IDEA, PyCharm, WebStorm, GoLand, RustRover, Android Studio, PhpStorm May work (untested): RubyMine, CLion, DataGrip

"Buy Me A Coffee"

IDE Index MCP Server provides AI coding assistants with access to the IDE's powerful code intelligence features through the Model Context Protocol (MCP).

Features

Multi-Language Support Advanced tools work across multiple languages based on available plugins:

  • Java & Kotlin - IntelliJ IDEA, Android Studio
  • Python - PyCharm (all editions), IntelliJ with Python plugin
  • JavaScript & TypeScript - WebStorm, IntelliJ Ultimate, PhpStorm
  • Go - GoLand, IntelliJ IDEA Ultimate with Go plugin
  • PHP - PhpStorm, IntelliJ Ultimate with PHP plugin
  • Rust - RustRover, IntelliJ IDEA Ultimate with Rust plugin, CLion

Universal Tools (All JetBrains IDEs)

  • Find References - Locate all usages of any symbol across the project
  • Go to Definition - Navigate to symbol declarations
  • Code Diagnostics - Access errors, warnings, and quick fixes
  • Index Status - Check if code intelligence is ready
  • Sync Files - Force sync VFS/PSI cache after external file changes
  • Build Project - Trigger IDE build with structured error/warning output (disabled by default)
  • Find Class - Fast class/interface search by name with camelCase matching
  • Find File - Fast file search by name using IDE's file index
  • Search Text - Text search using IDE's pre-built word index
  • Read File - Read file content by path or qualified name, including library sources (disabled by default)
  • Open File - Open a file in the editor with optional navigation (disabled by default)
  • Get Active File - Get currently active editor file(s) with cursor position (disabled by default)

Extended Tools (Language-Aware) These tools activate based on installed language plugins:

  • Type Hierarchy - Explore class inheritance chains
  • Call Hierarchy - Trace method/function call relationships
  • Find Implementations - Discover interface/abstract implementations
  • Symbol Search - Find by name with fuzzy/camelCase matching (disabled by default)
  • Find Super Methods - Navigate method override hierarchies
  • File Structure - View hierarchical file structure like IDE's Structure view (disabled by default)

Refactoring Tools

  • Rename Refactoring - Safe renaming with automatic related element renaming (getters/setters, overriding methods) - works across ALL languages, fully headless
  • Reformat Code - Reformat using project code style with import optimization (disabled by default)
  • Safe Delete - Remove code with usage checking (Java/Kotlin only)
  • Java to Kotlin Conversion - Convert Java to Kotlin using Intellij's built-in converter (Java only)

Why Use This Plugin?

Unlike simple text-based code analysis, this plugin gives AI assistants access to:

  • True semantic understanding through the IDE's AST and index
  • Cross-project reference resolution that works across files and modules
  • Multi-language support - automatically detects and uses language-specific handlers
  • Safe refactoring operations with automatic reference updates and undo support

Perfect for AI-assisted development workflows where accuracy and safety matter.

Table of Contents

Installation

Using the IDE built-in plugin system

Settings/Preferences > Plugins > Marketplace > Search for "IDE Index MCP Server" > Install

Using JetBrains Marketplace

Go to JetBrains Marketplace and install it by clicking the Install to ... button.

Manual Installation

Download the latest release and install it manually: Settings/Preferences > Plugins > βš™οΈ > Install plugin from disk...

Quick Start

  1. Install the plugin and restart your JetBrains IDE
  2. Open a project - the MCP server starts automatically with IDE-specific defaults:
    • IntelliJ IDEA: intellij-index on port 29170
    • PyCharm: pycharm-index on port 29172
    • WebStorm: webstorm-index on port 29173
    • Other IDEs: See IDE-Specific Defaults
  3. Configure your AI assistant using the "Install on Coding Agents" button (easiest) or manually
  4. Use the tool window (bottom panel: "Index MCP Server") to copy configuration or monitor commands
  5. Change port (optional): Click "Change port, disable tools" in the toolbar or go to Settings > Tools > Index MCP Server

Using the "Install on Coding Agents" Button

The easiest way to configure your AI assistant:

  1. Open the "Index MCP Server" tool window (bottom panel)
  2. Click the prominent "Install on Coding Agents" button on the right side of the toolbar
  3. A popup appears with two sections:
    • Install Now - For Claude Code CLI and Codex CLI: Runs the installation command automatically
    • Copy Configuration - For other clients: Copies the JSON config to your clipboard
  4. For "Copy Configuration" clients, paste the config into the appropriate config file

Client Configuration

Claude Code (CLI)

Use the "Install on Coding Agents" button in the tool window, or run this command (adjust name and port for your IDE):

# IntelliJ IDEA
claude mcp add --transport http intellij-index http://127.0.0.1:29170/index-mcp/streamable-http --scope user

# PyCharm
claude mcp add --transport http pycharm-index http://127.0.0.1:29172/index-mcp/streamable-http --scope user

# WebStorm
claude mcp add --transport http webstorm-index http://127.0.0.1:29173/index-mcp/streamable-http --scope user

Options:

  • --scope user - Adds globally for all projects
  • --scope project - Adds to current project only

To remove: claude mcp remove <server-name> (e.g., claude mcp remove intellij-index)

Codex CLI

Use the "Install on Coding Agents" button in the tool window, or run this command (adjust name and port for your IDE):

# IntelliJ IDEA
codex mcp add intellij-index --url http://127.0.0.1:29170/index-mcp/streamable-http

# PyCharm
codex mcp add pycharm-index --url http://127.0.0.1:29172/index-mcp/streamable-http

# WebStorm
codex mcp add webstorm-index --url http://127.0.0.1:29173/index-mcp/streamable-http

To remove: codex mcp remove <server-name> (e.g., codex mcp remove intellij-index)

Cursor

Add to .cursor/mcp.json in your project root or ~/.cursor/mcp.json globally (adjust name and port for your IDE):

{
  "mcpServers": {
    "intellij-index": {
      "url": "http://127.0.0.1:29170/index-mcp/streamable-http"
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json (adjust name and port for your IDE):

{
  "mcpServers": {
    "intellij-index": {
      "serverUrl": "http://127.0.0.1:29170/index-mcp/streamable-http"
    }
  }
}

VS Code (Generic MCP)

{
  "mcp.servers": {
    "intellij-index": {
      "url": "http://127.0.0.1:29170/index-mcp/streamable-http"
    }
  }
}

Note: Replace the server name and port with your IDE's defaults. See IDE-Specific Defaults below.

IDE-Specific Defaults

Each JetBrains IDE has a unique default port and server name to allow running multiple IDEs simultaneously without conflicts:

IDE Server Name Default Port
IntelliJ IDEA intellij-index 29170
Android Studio android-studio-index 29171
PyCharm pycharm-index 29172
WebStorm webstorm-index 29173
GoLand goland-index 29174
PhpStorm phpstorm-index 29175
RubyMine rubymine-index 29176
CLion clion-index 29177
RustRover rustrover-index 29178
DataGrip datagrip-index 29179

Tip: Use the "Install on Coding Agents" button in the tool window - it automatically uses the correct server name and port for your IDE.

Available Tools

The plugin provides 21 MCP tools organized by availability. Tools marked (disabled by default) can be enabled in Settings > Tools > Index MCP Server.

Universal Tools

These tools work in all supported JetBrains IDEs.

Tool Description
ide_find_references Find all references to a symbol across the entire project
ide_find_definition Find the definition/declaration location of a symbol
ide_find_class Search for classes/interfaces by name with camelCase/substring/wildcard matching
ide_find_file Search for files by name using IDE's file index
ide_search_text Text search using IDE's pre-built word index with context filtering
ide_diagnostics Analyze file problems with fresh IDE diagnostics, plus optional build/test results; intentions are best-effort
ide_index_status Check if the IDE is in dumb mode or smart mode
ide_sync_files Force sync IDE's virtual file system and PSI cache with external file changes
ide_build_project Build project using IDE's build system (JPS, Gradle, Maven) with structured errors (disabled by default)
ide_read_file Read file content by path or qualified name, including library/jar sources (disabled by default)
ide_get_active_file Get the currently active file(s) in the editor with cursor position (disabled by default)
ide_open_file Open a file in the editor with optional line/column navigation (disabled by default)
ide_refactor_rename Rename a symbol and update all references across the project (all languages)
ide_move_file Move a file to a new directory with automatic reference, import, and package updates
ide_reformat_code Reformat code using project code style with import optimization (disabled by default)

Extended Tools (Language-Aware)

These tools activate based on available language plugins:

Tool Description Languages
ide_type_hierarchy Get the complete type hierarchy (supertypes and subtypes) Java, Kotlin, Python, JS/TS, Go, PHP, Rust
ide_call_hierarchy Analyze method call relationships (callers or callees) Java, Kotlin, Python, JS/TS, Go, PHP, Rust
ide_find_implementations Find all implementations of an interface or abstract method Java, Kotlin, Python, JS/TS, PHP, Rust
ide_find_symbol Search for symbols (classes, methods, fields) by name with fuzzy/camelCase matching (disabled by default) Java, Kotlin, Python, JS/TS, Go, PHP, Rust
ide_find_super_methods Find the full inheritance hierarchy of methods that a method overrides/implements Java, Kotlin, Python, JS/TS, PHP
ide_file_structure Get hierarchical file structure (similar to IDE's Structure view) (disabled by default) Java, Kotlin, Python, JS/TS

Java-Specific Refactoring Tools

Tool Description
ide_convert_java_to_kotlin Convert Java files to Kotlin using IntelliJ's built-in converter (disabled by default, requires Java + Kotlin plugins)
ide_refactor_safe_delete Safely delete an element, checking for usages first (Java/Kotlin only)

Note: Refactoring tools modify source files. All changes support undo via Ctrl/Cmd+Z.

Tool Availability by IDE

Fully Tested:

IDE Universal Navigation Refactoring
IntelliJ IDEA βœ“ 14 tools βœ“ 6 tools βœ“ rename + reformat + safe delete + Javaβ†’Kotlin
Android Studio βœ“ 14 tools βœ“ 6 tools βœ“ rename + reformat + safe delete + Javaβ†’Kotlin
PyCharm βœ“ 14 tools βœ“ 6 tools βœ“ rename + reformat
WebStorm βœ“ 14 tools βœ“ 6 tools βœ“ rename + reformat
GoLand βœ“ 14 tools βœ“ 4 tools βœ“ rename + reformat
RustRover βœ“ 14 tools βœ“ 4 tools βœ“ rename + reformat
PhpStorm βœ“ 14 tools βœ“ 5 tools βœ“ rename + reformat

May Work (Untested):

IDE Universal Navigation Refactoring
RubyMine βœ“ 14 tools - βœ“ rename + reformat
CLion βœ“ 14 tools - βœ“ rename + reformat
DataGrip βœ“ 14 tools - βœ“ rename + reformat

Note: Navigation tools activate when language plugins are present. GoLand and RustRover have 4 navigation tools (no ide_find_implementations or ide_find_super_methods due to language semantics). PhpStorm has 5 (no ide_file_structure). The rename and reformat tools work across all languages. ide_convert_java_to_kotlin is available only in IntelliJ IDEA and Android Studio, requires both Java and Kotlin plugins, and is disabled by default.

For detailed tool documentation with parameters and examples, see USAGE.md.

Multi-Project Support

When multiple projects are open in a single IDE window, you must specify which project to use with the project_path parameter:

{
  "name": "ide_find_references",
  "arguments": {
    "project_path": "/Users/dev/myproject",
    "file": "src/Main.kt",
    "line": 10,
    "column": 5
  }
}

If project_path is omitted:

  • Single project open: That project is used automatically
  • Multiple projects open: An error is returned with the list of available projects

Workspace Projects

The plugin supports workspace projects where a single IDE window contains multiple sub-projects as modules with separate content roots. The project_path parameter accepts:

  • The workspace root path
  • A sub-project path (module content root)
  • A subdirectory of any open project

When an error occurs, the response returns available_projects. By default this includes workspace sub-projects so AI agents can discover valid module content roots. If you want smaller error payloads, switch Project list in error responses to Compact in plugin settings to return only top-level project roots.

Tool Window

The plugin adds an "Index MCP Server" tool window (bottom panel) that shows:

  • Server Status: Running indicator with server URL and port
  • Project Name: Currently active project
  • Command History: Log of all MCP tool calls with:
    • Timestamp
    • Tool name
    • Status (Success/Error/Pending)
    • Parameters and results (expandable)
    • Execution duration

Tool Window Actions

Action Description
Refresh Refresh server status and command history
Copy URL Copy the MCP server URL to clipboard
Clear History Clear the command history
Export History Export history to JSON or CSV file
Install on Coding Agents Install MCP server on AI assistants (prominent button on right)

Error Codes

JSON-RPC Standard Errors

Code Name Description
-32700 Parse Error Failed to parse JSON-RPC request
-32600 Invalid Request Invalid JSON-RPC request format
-32601 Method Not Found Unknown method name
-32602 Invalid Params Invalid or missing parameters
-32603 Internal Error Unexpected internal error

Custom MCP Errors

Code Name Description
-32001 Index Not Ready IDE is in dumb mode (indexing in progress)
-32002 File Not Found Specified file does not exist
-32003 Symbol Not Found No symbol found at the specified position
-32004 Refactoring Conflict Refactoring cannot be completed (e.g., name conflict)

Settings

Configure the plugin at Settings > Tools > Index MCP Server:

Setting Default Description
Server Port IDE-specific MCP server port (range: 1024-65535, auto-restart on change). See IDE-Specific Defaults
Server Host 127.0.0.1 Listening host. Change to 0.0.0.0 for remote/WSL access
Max History Size 100 Maximum number of commands to keep in history
Project List in Error Responses Expanded Controls available_projects detail for invalid/missing project_path errors. Expanded includes workspace sub-projects; Compact returns only top-level project roots
Sync External Changes false Sync external file changes before operations (WARNING: significant performance impact)
Disabled Tools 7 tools Per-tool enable/disable toggles. Some tools are disabled by default to keep the tool list focused

Requirements

  • JetBrains IDE 2025.1 or later (any IDE based on IntelliJ Platform)
  • JVM 21 or later
  • MCP Protocol 2025-03-26 (primary Streamable HTTP), with 2024-11-05 legacy SSE compatibility

Supported IDEs

Fully Tested:

  • IntelliJ IDEA (Community/Ultimate)
  • Android Studio
  • PyCharm (Community/Professional)
  • WebStorm
  • GoLand
  • RustRover
  • PhpStorm

May Work (Untested):

  • RubyMine
  • CLion
  • DataGrip

The plugin uses standard IntelliJ Platform APIs and should work on any IntelliJ-based IDE, but has only been tested on the IDEs listed above.

Architecture

The plugin runs a custom embedded Ktor CIO HTTP server with dual MCP transports:

Streamable HTTP Transport (Primary, MCP 2025-03-26)

AI Assistant ──────► POST /index-mcp/streamable-http (initialize or request)
                     ◄── JSON-RPC response or HTTP 202 Accepted
             ──────► POST /index-mcp/streamable-http (follow-up requests/notifications)
                     ◄── JSON-RPC response or HTTP 202 Accepted

The plugin uses stateless Streamable HTTP for the primary MCP transport. It does not issue Mcp-Session-Id headers, does not require session resumption, and does not implement or advertise authentication capabilities.

Legacy SSE Transport (MCP Inspector, older clients)

AI Assistant ──────► GET /index-mcp/sse              (establish SSE stream)
                     ◄── event: endpoint             (receive POST URL with sessionId)
             ──────► POST /index-mcp?sessionId=x     (JSON-RPC requests)
                     ◄── HTTP 202 Accepted
                     ◄── event: message              (JSON-RPC response via SSE)

This dual approach:

  • Primary MCP transport - Streamable HTTP per MCP 2025-03-26
  • MCP Inspector compatible - Legacy SSE transport per MCP 2024-11-05
  • Configurable port - IDE-specific default port, changeable in settings
  • Works with any MCP-compatible client
  • Single server instance across all open projects

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: ./gradlew test
  5. Submit a pull request

Development Setup

# Build the plugin
./gradlew build

# Run IDE with plugin installed
./gradlew runIde

# Run tests
./gradlew test

# Run plugin verification
./gradlew runPluginVerifier

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.


Plugin based on the IntelliJ Platform Plugin Template.