Skip to content

Repository files navigation

java-dev-ai-plugin

Java development skills for AI coding agents. Works with Claude Code and kiro-cli; skills are plain SKILL.md directories, so the same content serves both.

Skills install by default and switch themselves off when their prerequisite is missing: a SessionStart hook checks each skill's dependency and, when it is unreachable, sets Claude Code's skillOverrides to off so the skill stops loading. The moment the dependency comes back, the same hook removes the override. Nothing is deleted, and an override you set yourself is never touched.

Install

git clone https://github.com/ebasanez/java-dev-ai-plugin.git
cd java-dev-ai-plugin
./install.sh

The installer:

  1. detects which agent is running (env vars, process tree), which are installed (claude / kiro-cli on PATH, ~/.claude, ~/.kiro) and which the project uses (.claude/, CLAUDE.md, .kiro/) — asking only when several apply;
  2. runs each skill's pre-install check and shows the result;
  3. asks whether to install it (default yes for skills with defaultAnswer: true);
  4. copies the skill into the agent's skills directory;
  5. offers to register any MCP server the check discovered.

A failed pre-install check warns but does not stop the installation (checkIsBlocking: false in plugin.manifest.json).

Options

Flag Meaning
--agent claude-code|kiro-cli|both skip agent detection
--scope user|project (--user / --project) ~/.claude, ~/.kiro vs ./.claude, ./.kiro (default: user)
--with <id> / --without <id> answer an optional skill without prompting
--yes, -y non-interactive; use defaultAnswer from the manifest
--no-mcp never offer MCP registration

./uninstall.sh removes only the skills listed in the manifest (--purge also deletes .bak.* backups). MCP registrations are left in place.

Install targets

Agent User scope Project scope
Claude Code ${CLAUDE_CONFIG_DIR:-~/.claude}/skills/<id> ./.claude/skills/<id>
kiro-cli ${KIRO_HOME:-~/.kiro}/skills/<id> ./.kiro/skills/<id>

As a Claude Code plugin

/plugin marketplace add ebasanez/java-dev-ai-plugin
/plugin install java-dev-ai-plugin@java-dev-ai-plugin

/plugin marketplace add also accepts the full clone URL (https://github.com/ebasanez/java-dev-ai-plugin.git) or a local checkout path.

This installs every skill (they live in skills/, which Claude Code auto-loads) and registers the SessionStart hook that enables/disables them per session. No further step is needed for Claude Code — install.sh is for kiro-cli, for non-plugin installs, and for registering the MCP server.

The MCP server definition

The plugin ships .mcp.json at its root, which Claude Code reads on install — so the IDE's MCP server is registered for you and execute_tool is available without any claude mcp add:

{
  "mcpServers": {
    "intellij-idea": { "type": "http", "url": "http://127.0.0.1:64342/stream" }
  }
}

64342 is the first port an IntelliJ-based IDE takes; a second IDE lands on 64343 and so on, and the port is not configurable (IJPL-207839). If yours differs, copy the exact URL from Settings | Tools | MCP Server and either edit this file or register the server yourself — the status line names whichever config file it found.

These are the values IntelliJ's own Auto-Configure writes, and streamable HTTP is the only transport a plain script can drive, so it is what the probe prefers.

The probe only ever touches the MCP transport endpoints: /stream (reported as http), then /sse (reported as sse). It deliberately never calls the legacy /api/mcp/list_tools — current IDEs do not serve it, and all IDE work goes through execute_tool anyway. A server offering only that endpoint is treated as not found. What the probe found drives registration, so install.sh passes the matching --transport (IDEA_MCP_URL / IDEA_MCP_TRANSPORT override both).

Keep exactly one entry for the IDE. Running Auto-Configure on a project adds its own server (named idea) pointing at the same port — two registrations of one IDE means its whole toolset is loaded twice into context every turn.

Start Claude with --plugin-dir-no-mcp to make the engine ignore this file entirely.

kiro-cli does not read a plugin's .mcp.json, and neither does a plain git clone + ./install.sh — so the installer registers the server itself, whether or not an IDE is running. With one detected it uses the probed endpoint and transport; with none it falls back to the values in this .mcp.json, so the registration is simply inert until the IDE starts. It skips agents where the server name is already registered, so running it alongside a plugin install does not create duplicates.

Self-disabling skills

The hook (hooks/session-start-mcp-check.sh) runs each skill's preinstallCheck and:

Check result Action
fails skillOverrides["java-dev-ai-plugin:<skill>"] = "off" — the skill stops loading and stops costing context
passes that override is removed — the skill comes back

It then reports the current state at every session start:

java-dev-ai-plugin status:
  IntelliJ IDEA MCP server: available at http://127.0.0.1:64342/stream (http transport, tool count unknown until a session opens)
  IntelliJ IDEA MCP tooling: loaded - MCP server 'intellij-idea' is registered in <plugin>/.mcp.json, so execute_tool is callable
  Skill intellij-idea-mcp-helper: loaded

The three lines are independent: the IDE can be up while its MCP server is not registered with the agent (so execute_tool is missing), and the skill can be loaded while the IDE is down. A line only ends in - disabled just now / - re-enabled just now when this run actually changed something.

The report is emitted as hook JSON — systemMessage so you see it in the UI, and hookSpecificOutput.additionalContext so the model knows the state too. Plain stdout from a SessionStart hook only ever reaches the model, which is why the status would otherwise appear to be missing.

Rules it follows:

  • it only ever changes overrides it wrote itself (tracked in ${XDG_STATE_HOME:-~/.local/state}/java-dev-ai-plugin/); an override you set by hand, or edited afterwards, is left alone;
  • it writes to .claude/settings.local.json in the project — the same file /skills uses;
  • it reads MCP registration from .mcp.json, ~/.claude.json and the agent's settings.json directly, rather than shelling out to claude mcp get;
  • probe results are cached for 60s so back-to-back sessions do not re-probe.
Variable Effect
JDAP_OVERRIDE_SCOPE local (default), project or user settings file
JDAP_DISABLED_VALUE off (default), name-only, or user-invocable-only
JDAP_PROBE_CACHE_TTL probe cache lifetime in seconds (default 60)

To opt out permanently, set the override yourself — the hook will then keep its hands off:

{ "skillOverrides": { "java-dev-ai-plugin:intellij-idea-mcp-helper": "off" } }

kiro-cli has no equivalent setting, so there "disabled" means simply not copying the skill in (install.sh --without <id>, or uninstall.sh).

Skills

intellij-idea-mcp-helper (optional)

Routes Java-semantic work to a running IntelliJ IDEA MCP server instead of grep/sed: renaming a Java element, semantic/symbol search, detecting file errors, linting/reformatting a file, and listing project dependencies or modules.

Requires IntelliJ IDEA 2025.2+ with Settings | Tools | MCP Server enabled (earlier versions can use the JetBrains MCP Server plugin).

Install check. scripts/probe_mcp.sh looks for the IDE on ports 64342-64352, then 63342 and 6365, on 127.0.0.1 and — under WSL — the default gateway. Not finding one is only a warning; the skill installs and stays inert until an IDE is up.

Tool resolution. The bundled reference.md maps intents to tool names and their expected arguments. It is explicitly marked as approximate: names drift between IDE versions and depend on Exposed Tools, and there is no HTTP endpoint to enumerate them — current IDEs do not serve /api/mcp/list_tools, so nothing here calls it. When a call is rejected, the IDE's own error message is the authority.

Invocation. Everything goes through the router — no direct tool calls:

execute_tool(
  command: "rename_refactoring --pathInProject src/main/java/com/example/Foo.java --symbolName Foo --newName Bar",
  projectPath: "/abs/path/to/project"
)

Environment overrides

Variable Effect
IDEA_MCP_HOST host to probe first (needed when the IDE runs on Windows and the agent in WSL)
IDEA_MCP_PORT / IDE_PORT port to probe first
IDEA_MCP_URL exact URL to register with the agent
IDEA_MCP_TRANSPORT http (default) or sse, overriding what the probe detected
IDEA_MCP_BUDGET probe wall-clock budget in seconds (default 6)

Adding another skill

  1. Create skills/<id>/SKILL.md (frontmatter limited to name and description so both agents parse it).
  2. Add an entry to plugin.manifest.json:
{
  "id": "<id>",
  "path": "skills/<id>",
  "optional": true,
  "defaultAnswer": true,
  "summary": "one line shown at the install prompt",
  "preinstallCheck": "skills/<id>/scripts/check.sh",
  "checkIsBlocking": false,
  "mcpServerName": "<name>",
  "skillOverrideKey": "java-dev-ai-plugin:<id>",
  "autoDisableWhenCheckFails": true
}
Field Effect
preinstallCheck must exit 0 when satisfied and print one line of JSON
checkIsBlocking true aborts the install when the check fails; false only warns
mcpServerName with a baseUrl in the check's JSON, enables the MCP registration offer
autoDisableWhenCheckFails the SessionStart hook manages this skill's skillOverrides entry
skillOverrideKey the settings key to write (defaults to the bare skill id)

Omit autoDisableWhenCheckFails for skills with no external dependency — they then stay loaded unconditionally.

Tests

./tests/run_all.sh

Syntax-checks every script, then runs detection, probe and install tests against a fake IDE MCP endpoint (tests/fake_ide.py) and a temporary HOME.

References

About

A customizable multiu-agent AI plugin for Java development

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages