{"slug":"minecraft-plugin-dev-2","title":"minecraft-plugin-dev","summary":"Create, modify, and debug server plugins for current Paper 26.x on Java 25 or legacy Bukkit-derived 1.21.x servers on Java 21. Use for JavaPlugin APIs, events, commands, schedulers, configuration, PDC, and Adventure, not client mods or vanilla datapacks.","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-07T18:38:48.141987Z","repo":{"url":"https://github.com/Jahrome907/minecraft-agent-skills","stars":151,"forks":9,"license":"MIT","updatedAt":"2026-09-13T05:52:30Z"},"bodyHtml":"<hr>\n<h2>name: minecraft-plugin-dev\ndescription: \"Create, modify, and debug server plugins for current Paper 26.x on Java 25 or legacy Bukkit-derived 1.21.x servers on Java 21. Use for JavaPlugin APIs, events, commands, schedulers, configuration, PDC, and Adventure, not client mods or vanilla datapacks.\"</h2>\n<h1>Minecraft Plugin Development Skill</h1>\n<h2>Platform Overview</h2>\n<table>\n<thead>\n<tr>\n<th>Platform</th>\n<th>Base API</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Paper</strong></td>\n<td>Bukkit/Spigot + Paper extensions</td>\n<td>Recommended; async chunk loading, Adventure native</td>\n</tr>\n<tr>\n<td><strong>Spigot</strong></td>\n<td>Bukkit + Spigot extensions</td>\n<td>Legacy; fewer APIs, slower</td>\n</tr>\n<tr>\n<td><strong>Bukkit</strong></td>\n<td>Base API only</td>\n<td>Avoid for new plugins</td>\n</tr>\n<tr>\n<td><strong>Folia</strong></td>\n<td>Paper fork</td>\n<td>Region-threaded; requires special scheduler APIs</td>\n</tr>\n</tbody>\n</table>\n<blockquote>\n<p>Paper is the recommended target. Paper includes all Bukkit and Spigot APIs plus\nsignificant performance improvements and additional APIs.</p>\n</blockquote>\n<h3>Routing Boundaries</h3>\n<ul>\n<li><code>Use when</code>: the target is server-side Paper/Bukkit/Spigot plugin behavior with JavaPlugin APIs.</li>\n<li><code>Do not use when</code>: the task requires client-side installable mods or loader APIs (<code>minecraft-modding</code> / <code>minecraft-multiloader</code>).</li>\n<li><code>Do not use when</code>: the task is pure vanilla datapack/command content (<code>minecraft-datapack</code> / <code>minecraft-commands-scripting</code>).</li>\n</ul>\n<h2>Bundled References</h2>\n<ul>\n<li>Read <code>references/runtime-patterns.md</code> when the task touches scheduling, Folia support, PDC, Adventure/MiniMessage, YAML config, Vault, or Paper-specific APIs.</li>\n<li>Read <code>references/paper-plugin-commands.md</code> for a Paper-only <code>paper-plugin.yml</code> project or Brigadier command registration.</li>\n</ul>\n<hr>\n<h2>Project Setup</h2>\n<p>The examples below target current Paper 26.2 and Java 25. For an existing\n1.21.x plugin, preserve its <code>1.21.x-R0.1-SNAPSHOT</code> dependency, Java 21\ntoolchain, and matching <code>api-version</code> until the project is intentionally ported.</p>\n<h3><code>settings.gradle.kts</code></h3>\n<pre><code>rootProject.name = \"my-plugin\"\n</code></pre>\n<h3><code>build.gradle.kts</code></h3>\n<pre><code>plugins {\n    java\n}\n\ngroup = \"com.example\"\nversion = \"1.0.0-SNAPSHOT\"\n\nrepositories {\n    mavenCentral()\n    maven(\"https://repo.papermc.io/repository/maven-public/\")\n}\n\ndependencies {\n    compileOnly(\"io.papermc.paper:paper-api:26.2.build.+\")\n}\n\njava {\n    toolchain.languageVersion.set(JavaLanguageVersion.of(25))\n}\n\ntasks {\n    processResources {\n        // Substitutes ${version} in plugin.yml with the Gradle project version\n        filesMatching(listOf(\"plugin.yml\", \"paper-plugin.yml\")) {\n            expand(\"version\" to project.version)\n        }\n    }\n}\n</code></pre>\n<p>Add Shadow only when the plugin has runtime libraries that must be bundled and\nrelocated. Paper and optional plugin APIs such as Vault remain <code>compileOnly</code> and\nmust not be shaded into the plugin JAR.</p>\n<h3><code>gradle/wrapper/gradle-wrapper.properties</code></h3>\n<pre><code>distributionUrl=https\\://services.gradle.org/distributions/gradle-9.1.0-bin.zip\n</code></pre>\n<p>Gradle 8.8 cannot run on Java 25. Use Gradle 9.1 or newer for a current Java 25\nproject. Preserve the existing wrapper and Java 21 toolchain for a legacy 1.21.x\nproject unless its build is intentionally upgraded and verified.</p>\n<hr>\n<h2>Project Layout</h2>\n<pre><code>my-plugin/\n├── build.gradle.kts\n├── settings.gradle.kts\n├── gradle/\n│   └── wrapper/\n│       └── gradle-wrapper.properties\n└── src/main/\n    ├── java/com/example/myplugin/\n    │   ├── MyPlugin.java          ← main class (extends JavaPlugin)\n    │   ├── listeners/\n    │   │   └── PlayerListener.java\n    │   ├── commands/\n    │   │   └── MyCommand.java\n    │   └── managers/\n    │       └── DataManager.java\n    └── resources/\n        ├── plugin.yml            ← Bukkit-compatible descriptor\n        ├── paper-plugin.yml      ← active descriptor for a Paper plugin\n        └── config.yml\n</code></pre>\n<hr>\n<h2>Core Files</h2>\n<h3><code>plugin.yml</code> (Bukkit-compatible default)</h3>\n<pre><code>name: MyPlugin\nversion: \"${version}\"\nmain: com.example.myplugin.MyPlugin\ndescription: An example Paper plugin\nauthor: YourName\nwebsite: https://github.com/example/my-plugin\napi-version: '26.2'\n\ncommands:\n  myplugin:\n    description: Main plugin command\n    usage: /myplugin &lt;subcommand&gt;\n    permission: myplugin.use\n    aliases: [mp]\n\npermissions:\n  myplugin.use:\n    description: Allows use of /myplugin\n    default: true\n  myplugin.admin:\n    description: Admin access\n    default: op\n</code></pre>\n<blockquote>\n<p>Match <code>api-version</code> to the oldest Paper API the plugin intentionally supports.\nCurrent Paper examples use <code>26.2</code>; legacy <code>1.21</code> and positive <code>1.21.&lt;patch&gt;</code>\nvalues remain valid for older servers. A server older than the declared value\nrefuses to load the plugin.</p>\n</blockquote>\n<h3><code>paper-plugin.yml</code> (experimental Paper-only format)</h3>\n<p>Prefer <code>plugin.yml</code> for Bukkit-compatible plugins. Use <code>paper-plugin.yml</code> only\nwhen the JAR is intentionally Paper-only and needs Paper-plugin behavior such\nas bootstrapping, loaders, or classloading isolation. It can be the only\ndescriptor, but is not a drop-in replacement: Paper plugins do not use a\n<code>commands</code> field or <code>getCommand(...)</code> registration. Read\n<a href=\"references/paper-plugin-commands.md\"><code>references/paper-plugin-commands.md</code></a>\nfor the paired descriptor, main class, and Brigadier lifecycle registration.</p>\n<p>When one JAR ships both descriptors, keep their shared metadata and main class\naligned. Do not combine the Paper-only sample with the Bukkit-compatible\n<code>MyPlugin</code> sample below.</p>\n<h3>Bukkit-compatible main class</h3>\n<pre><code>package com.example.myplugin;\n\nimport com.example.myplugin.commands.MyCommand;\nimport com.example.myplugin.listeners.PlayerListener;\nimport org.bukkit.plugin.java.JavaPlugin;\n\npublic final class MyPlugin extends JavaPlugin {\n\n    @Override\n    public void onEnable() {\n        saveDefaultConfig();\n\n        // Register listeners\n        getServer().getPluginManager().registerEvents(new PlayerListener(), this);\n\n        // Register commands\n        var cmd = getCommand(\"myplugin\");\n        if (cmd == null) {\n            throw new IllegalStateException(\"myplugin command is missing from plugin.yml\");\n        }\n        var handler = new MyCommand(this);\n        cmd.setExecutor(handler);\n        cmd.setTabCompleter(handler);\n\n        getLogger().info(\"MyPlugin enabled!\");\n    }\n\n    @Override\n    public void onDisable() {\n        getLogger().info(\"MyPlugin disabled.\");\n    }\n\n}\n</code></pre>\n<hr>\n<h2>Event Listeners</h2>\n<pre><code>package com.example.myplugin.listeners;\n\nimport net.kyori.adventure.text.Component;\nimport net.kyori.adventure.text.format.NamedTextColor;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.EventPriority;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.entity.PlayerDeathEvent;\nimport org.bukkit.event.player.PlayerJoinEvent;\nimport org.bukkit.event.player.PlayerQuitEvent;\n\npublic class PlayerListener implements Listener {\n\n    @EventHandler(priority = EventPriority.NORMAL)\n    public void onPlayerJoin(PlayerJoinEvent event) {\n        event.joinMessage(\n            Component.text(event.getPlayer().getName() + \" joined!\", NamedTextColor.GREEN)\n        );\n    }\n\n    @EventHandler\n    public void onPlayerQuit(PlayerQuitEvent event) {\n        event.quitMessage(\n            Component.text(event.getPlayer().getName() + \" left.\", NamedTextColor.YELLOW)\n        );\n    }\n\n    @EventHandler\n    public void onPlayerDeath(PlayerDeathEvent event) {\n        // Modify death message using Adventure components\n        event.deathMessage(\n            Component.text(\"☠ \", NamedTextColor.RED)\n                .append(Component.text(event.getPlayer().getName(), NamedTextColor.WHITE))\n                .append(Component.text(\" died!\", NamedTextColor.RED))\n        );\n    }\n}\n</code></pre>\n<h3>EventPriority order</h3>\n<p><code>LOWEST → LOW → NORMAL → HIGH → HIGHEST → MONITOR</code><br>\nUse <code>MONITOR</code> for logging only (never modify outcome). On events that implement\n<code>Cancellable</code>, use <code>ignoreCancelled = true</code> unless you need cancelled events.</p>\n<h3>Cancellable events</h3>\n<pre><code>@EventHandler\npublic void onBlockBreak(BlockBreakEvent event) {\n    if (event.getPlayer().hasPermission(\"myplugin.break.deny\")) {\n        event.setCancelled(true);\n        event.getPlayer().sendMessage(Component.text(\"You cannot break blocks!\", NamedTextColor.RED));\n    }\n}\n</code></pre>\n<hr>\n<h2>Commands</h2>\n<p>This section is for the <code>plugin.yml</code> path above. Its declared command enables\n<code>getCommand(\"myplugin\")</code>. For a Paper-only descriptor, use the Brigadier\nlifecycle example in <a href=\"references/paper-plugin-commands.md\"><code>references/paper-plugin-commands.md</code></a>.</p>\n<pre><code>package com.example.myplugin.commands;\n\nimport com.example.myplugin.MyPlugin;\nimport net.kyori.adventure.text.Component;\nimport net.kyori.adventure.text.format.NamedTextColor;\nimport org.bukkit.command.Command;\nimport org.bukkit.command.CommandExecutor;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.command.TabCompleter;\nimport org.bukkit.entity.Player;\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.List;\nimport java.util.Locale;\n\npublic class MyCommand implements CommandExecutor, TabCompleter {\n\n    private final MyPlugin plugin;\n\n    public MyCommand(MyPlugin plugin) {\n        this.plugin = plugin;\n    }\n\n    @Override\n    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,\n                             @NotNull String label, @NotNull String[] args) {\n        if (!(sender instanceof Player player)) {\n            sender.sendMessage(Component.text(\"Only players can use this command.\", NamedTextColor.RED));\n            return true;\n        }\n\n        if (!player.hasPermission(\"myplugin.use\")) {\n            player.sendMessage(Component.text(\"No permission.\", NamedTextColor.RED));\n            return true;\n        }\n\n        if (args.length == 0) {\n            player.sendMessage(Component.text(\"Usage: /myplugin &lt;reload|info&gt;\", NamedTextColor.YELLOW));\n            return true;\n        }\n\n        return switch (args[0].toLowerCase(Locale.ROOT)) {\n            case \"reload\" -&gt; {\n                plugin.reloadConfig();\n                player.sendMessage(Component.text(\"Config reloaded.\", NamedTextColor.GREEN));\n                yield true;\n            }\n            case \"info\" -&gt; {\n                player.sendMessage(Component.text(\"Version: \" + plugin.getDescription().getVersion(), NamedTextColor.AQUA));\n                yield true;\n            }\n            default -&gt; {\n                player.sendMessage(Component.text(\"Unknown subcommand.\", NamedTextColor.RED));\n                yield true;\n            }\n        };\n    }\n\n    @Override\n    public @Nullable List&lt;String&gt; onTabComplete(@NotNull CommandSender sender, @NotNull Command command,\n                                                @NotNull String label, @NotNull String[] args) {\n        if (args.length == 1) {\n            return List.of(\"reload\", \"info\").stream()\n                .filter(s -&gt; s.startsWith(args[0].toLowerCase(Locale.ROOT)))\n                .toList();\n        }\n        return List.of();\n    }\n}\n</code></pre>\n<hr>\n<h2>Schedulers</h2>\n<p>For classic Paper plugins, <code>BukkitScheduler</code> is still fine. If you claim Folia support,\nroute player, entity, region, global, and async work through the matching Folia-aware\nscheduler. Keep scheduling behind a small project-local interface when one plugin must\nsupport both Paper and Folia.</p>\n<p>See <code>references/runtime-patterns.md</code> for copy-ready sync, async, cancelable, and\nFolia-safe scheduler examples.</p>\n<hr>\n<h2>Persistent Data Container (PDC)</h2>\n<p>PDC stores arbitrary data on any <code>PersistentDataHolder</code> (players, entities, items, chunks).\nData is saved with the world and persists across restarts.</p>\n<p>Create <code>NamespacedKey</code> instances once, keep data types stable after release, and use\nPDC for small metadata rather than large datasets. Prefer config files or a database\nfor large or query-heavy plugin state.</p>\n<p>See <code>references/runtime-patterns.md</code> for player, item, chunk, and world PDC examples.</p>\n<hr>\n<h2>Adventure Text Components</h2>\n<p>Paper uses <a href=\"https://docs.advntr.dev/\">Adventure</a> natively for all text. No legacy chat colors.\nUse <code>Component</code> builders for code-owned messages and MiniMessage for config-driven\nmessages. Avoid legacy <code>ChatColor</code> unless the target project already depends on it\nfor compatibility.</p>\n<p>See <code>references/runtime-patterns.md</code> for simple messages, hover/click events,\nMiniMessage parsing, titles, and action bars.</p>\n<hr>\n<h2>Configuration (YAML)</h2>\n<h3><code>src/main/resources/config.yml</code></h3>\n<pre><code># Default config\nsettings:\n  max-players: 20\n  welcome-message: \"&lt;green&gt;Welcome to the server!\"\n  cooldown-seconds: 30\n\ndatabase:\n  host: localhost\n  port: 3306\n  name: myplugin_db\n</code></pre>\n<h3>Accessing config values</h3>\n<p>Call <code>saveDefaultConfig()</code> in <code>onEnable()</code>, provide explicit defaults when reading\nvalues, and validate config shape before starting long-running tasks.</p>\n<h3>Custom config file</h3>\n<p>Use custom YAML files only when separating user config from mutable plugin data is\nworth the extra file handling. Keep blocking disk writes off hot event paths.</p>\n<p>See <code>references/runtime-patterns.md</code> for config read/write and custom YAML examples.</p>\n<hr>\n<h2>Vault Integration (Economy / Permissions)</h2>\n<p>Declare Vault as <code>compileOnly</code>, soft-depend on it in plugin metadata, and disable\neconomy features cleanly when the service provider is unavailable. Never assume a\nVault-compatible economy plugin is installed just because Vault itself is present.</p>\n<p>When Vault support is required, add the JitPack repository and\n<code>compileOnly(\"com.github.MilkBowl:VaultAPI:1.7\")</code> to the Gradle build.</p>\n<p>See <code>references/runtime-patterns.md</code> for a minimal economy setup and charge example.</p>\n<hr>\n<h2>Paper-Specific APIs</h2>\n<p>Use Paper APIs when they remove main-thread blocking or simplify Adventure-native\nbehavior. Keep optional plugin integrations behind presence checks and metadata\nsoft-dependencies.</p>\n<p>See <code>references/runtime-patterns.md</code> for async chunk loading, custom item meta,\nprofile lookup, and protection-plugin integration examples.</p>\n<hr>\n<h2>Common Tasks Checklist</h2>\n<h3>Creating a new event listener</h3>\n<ul>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Create class implementing <code>Listener</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Annotate methods with <code>@EventHandler</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Call <code>getServer().getPluginManager().registerEvents(listener, plugin)</code> in <code>onEnable()</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> On cancellable events, add <code>ignoreCancelled = true</code> unless you need cancelled events</li>\n</ul>\n<h3>Adding a new command</h3>\n<ul>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For a Bukkit-compatible plugin, define the command in <code>plugin.yml</code>, create a <code>CommandExecutor</code>, and register it with <code>getCommand(\"name\")</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For a Paper-only plugin, register the command through <code>LifecycleEvents.COMMANDS</code>; do not add a <code>commands</code> field</li>\n</ul>\n<h3>Saving plugin data</h3>\n<ul>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For simple values: use <code>config.yml</code> via <code>getConfig()</code> / <code>saveConfig()</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For per-entity data: use PDC with a <code>NamespacedKey</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> For large datasets: use async scheduler + file I/O or a database</li>\n</ul>\n<h3>Scheduling a repeating task</h3>\n<ul>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Determine if task needs main thread (use <code>runTaskTimer</code>) or is I/O (use <code>runTaskTimerAsynchronously</code>)</li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Store the <code>BukkitTask</code> reference so you can cancel in <code>onDisable()</code></li>\n<li><input disabled=\"disabled\" type=\"checkbox\"> Cancel all tasks in <code>onDisable()</code> or use <code>getServer().getScheduler().cancelTasks(plugin)</code></li>\n</ul>\n<hr>\n<h2>Build, Validate, and Run</h2>\n<ol>\n<li>Build the plugin JAR:\n<pre><code>./gradlew build\n# Output: build/libs/my-plugin-1.0.0-SNAPSHOT.jar\n</code></pre>\n</li>\n<li>Run the bundled validator to catch config and layout errors:\n<pre><code>./scripts/validate-plugin-layout.sh --root /path/to/plugin-project\n# Strict mode treats warnings as failures:\n./scripts/validate-plugin-layout.sh --root /path/to/plugin-project --strict\n</code></pre>\nThe validator requires Node and includes its own YAML parser for descriptor checks.</li>\n<li>Fix any reported errors and re-run until clean.</li>\n<li>Deploy: copy the built JAR to <code>server/plugins/</code> and restart the Paper server.\nIf the real project already applies a Paper dev-server plugin such as <code>xyz.jpenilla.run-paper</code>,\nuse that project's documented dev task instead of assuming <code>./gradlew runServer</code> exists.</li>\n</ol>\n<p>The validator checks:</p>\n<ul>\n<li>active <code>plugin.yml</code> or <code>paper-plugin.yml</code> required keys (<code>name</code>, <code>version</code>, <code>main</code>, <code>api-version</code>) and repo-supported current <code>26.&lt;release&gt;</code> or legacy <code>1.21</code> / positive <code>1.21.&lt;patch&gt;</code> values, with warnings for versions newer than the documented examples</li>\n<li>cross-descriptor metadata consistency when both descriptors are present; <code>paper-plugin.yml</code> is selected as active</li>\n<li>Active main class path exists and extends <code>JavaPlugin</code></li>\n<li>actual server <code>/reload</code> anti-patterns such as <code>Bukkit.reload()</code> or dispatching the server reload command</li>\n</ul>\n<hr>\n<h2>References</h2>\n<ul>\n<li>Paper API Javadoc: <a href=\"https://jd.papermc.io/paper/\">https://jd.papermc.io/paper/</a></li>\n<li>Paper plugin descriptor: <a href=\"https://docs.papermc.io/paper/dev/plugin-yml/\">https://docs.papermc.io/paper/dev/plugin-yml/</a></li>\n<li>Paper plugins: <a href=\"https://docs.papermc.io/paper/dev/getting-started/paper-plugins/\">https://docs.papermc.io/paper/dev/getting-started/paper-plugins/</a></li>\n<li>Paper Brigadier registration: <a href=\"https://docs.papermc.io/paper/dev/command-api/basics/registration/\">https://docs.papermc.io/paper/dev/command-api/basics/registration/</a></li>\n<li>Gradle Java compatibility: <a href=\"https://docs.gradle.org/current/userguide/compatibility.html\">https://docs.gradle.org/current/userguide/compatibility.html</a></li>\n<li>Adventure (text API): <a href=\"https://docs.advntr.dev/\">https://docs.advntr.dev/</a></li>\n<li>MiniMessage format: <a href=\"https://docs.advntr.dev/minimessage/format.html\">https://docs.advntr.dev/minimessage/format.html</a></li>\n<li>Vault API: <a href=\"https://github.com/MilkBowl/VaultAPI\">https://github.com/MilkBowl/VaultAPI</a></li>\n<li>Bukkit API Javadoc: <a href=\"https://javadoc.io/doc/org.bukkit/bukkit/\">https://javadoc.io/doc/org.bukkit/bukkit/</a></li>\n<li>run-task Gradle plugin: <a href=\"https://github.com/jpenilla/run-task\">https://github.com/jpenilla/run-task</a></li>\n</ul>\n","files":[{"path":"references/paper-plugin-commands.md","sizeBytes":2655,"isText":true},{"path":"references/runtime-patterns.md","sizeBytes":7695,"isText":true},{"path":"scripts/validate-plugin-layout.sh","sizeBytes":11085,"isText":true},{"path":"scripts/vendor/js-yaml.min.cjs","sizeBytes":61672,"isText":false},{"path":"scripts/vendor/LICENSE.js-yaml","sizeBytes":1084,"isText":false},{"path":"SKILL.md","sizeBytes":17217,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-07T18:39:45.942669Z","sha256":"658A4C05FDBB43B7BB291193450BBFEA842D4BE232B7364644167AE6EE31E7AA","sizeBytes":33216},"review":null,"source":{"repositoryUrl":"https://github.com/Jahrome907/minecraft-agent-skills","path":".claude/skills/minecraft-plugin-dev","license":"MIT","commit":"dd57c5a97741cdc0eb5bb3a8f876581a4f09eeb0","subtreeSha":"65C4413B8D41177316D9C694E46EC965C106A759707D01AEBA2F7E9E2390351D","lastSyncedAt":"2026-09-25T06:49:17.478439Z"},"reviewedAt":"2026-09-07T18:42:02.855482Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/Jahrome907/minecraft-agent-skills/tree/main/.claude/skills/minecraft-plugin-dev"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install jahrome907-minecraft-agent-skills@llmmart"},{"target":"git","command":"git clone https://github.com/Jahrome907/minecraft-agent-skills.git"}]}