All posts
October 1, 202610 min readไทยEN

When AI Writes Minecraft Plugins with the PaperMC Javadocs by Its Side

Tired of AI calling methods that don't exist, I built an MCP server that lets it check the PaperMC Javadocs before writing plugin code.

MCPMinecraftPaperMCAI

Pretty much everyone who writes code leans on AI these days, whether it's Claude, Cursor or something else.

But every time I use it for a Minecraft plugin, I hit the same wall. It answers from memory, and that memory rarely matches the PaperMC version I'm actually on. The usual suspects:

  • Calling methods that don't exist
  • Using APIs that were deprecated ages ago
  • Passing the wrong parameter types
  • Mixing up the Spigot and Paper APIs
  • Code that looks great but won't compile

So I figured, what if it just went and checked the Javadocs itself before writing anything? That should fix a lot of it.

That's how MineDocs MCP came about (github.com/FewPz/minedocs-mcp). It's a small open-source MCP server that lets AI look up classes, methods and fields, and check what's deprecated, straight from the PaperMC Javadocs before it starts writing code.

What's MCP?

In case you haven't run into it yet, MCP stands for Model Context Protocol. It's a standard that lets AI apps plug into outside tools and data, through things called Tools, Resources and Prompts.

For MineDocs, it looks roughly like this:

The AI asks over MCP, and MineDocs goes and reads the Javadocs for it

And just like that, the AI doesn't have to guess anymore.

Why AI keeps getting plugins wrong

Say you ask an AI something like:

text
Create a Minecraft plugin that teleports the player to a given location.

You'll probably get something like this back:

java
player.teleport(location);

That one's easy, no problem there. But once a plugin gets bigger, you start needing to know a lot more, like:

  • What parameters does this method take?
  • What does it return?
  • How many overloads are there?
  • Are there any gotchas?
  • Which version did it show up in?
  • Is it deprecated yet?

The catch is that the AI might be working off old info, while Minecraft's API keeps shifting every version. Letting it write purely from memory is a bit risky. I'd much rather it checked first, then wrote the code.

What MineDocs does

The idea is honestly really simple. It goes to the PaperMC Javadocs and:

  1. 1Fetches the Javadoc page
  2. 2Parses the HTML
  3. 3Keeps only the parts that matter
  4. 4Turns it into Markdown
  5. 5Sends that back for the AI to read

Inside, it's split up like this:

How MineDocs is put together

The server is built on the MCP SDK and talks to the client over StdioServerTransport.

The tools

There are six of them right now.

ToolWhat it does
get_paper_class_infoShows info about a class
search_paper_classesFinds classes by keyword
get_method_detailsShows the details of a method
get_field_summaryLists fields and constants
list_package_classesLists what's in a package
search_deprecatedFinds what's been deprecated
Tool 01

Finding a class

Say you don't know which class handles players. Just ask:

text
Search PaperMC for classes related to "Player"

MineDocs looks for matching classes and sends back their full names:

text
org.bukkit.entity.Player
org.bukkit.event.player.PlayerEvent
org.bukkit.event.player.PlayerMoveEvent
...

Once it has the name, the AI can keep digging from there.

Tool 02

Looking inside a class

Now that we know it's org.bukkit.entity.Player, we can ask for more:

text
Look up org.bukkit.entity.Player in PaperMC
and show me its methods.

It pulls that class's Javadoc page, grabs the signature, description, method summary and method details, and formats it all as Markdown for the AI. Under the hood it's just a few steps in a row:

HTML goes in, Markdown comes out
Tool 03

Just one method

Sometimes you don't want the whole class, just one method:

text
What are the parameters for Player's teleport method?

That's what get_method_details is for. You pass it a class and a method name (say org.bukkit.entity.Player and teleport) and it finds it in the Javadoc for you.

The part I find really handy is that if a method has overloads, you get all of them:

java
teleport(Location location)

teleport(Location location, TeleportCause cause)

So the AI can see every way to call it instead of guessing the parameters.

Tool 04

Checking for deprecated APIs

This one comes up all the time: the code compiles fine, but it's using an API you're not supposed to use anymore.

search_deprecated is there to catch that. You can ask things like:

text
Is Player.getDisplayName() deprecated?

Find deprecated PaperMC APIs related to Timing.

It pulls the deprecated list and filters it by what you asked, so the AI finds out that the method it's used to might not be the one to use anymore.

A look at the code

The project isn't big. Files are split up by what they do:

text
src/
├── server.ts
├── tools/
│   ├── getPaperClassInfo.ts
│   ├── searchPaperClasses.ts
│   ├── getMethodDetails.ts
│   ├── getFieldSummary.ts
│   ├── listPackageClasses.ts
│   └── searchDeprecated.ts
└── lib/
    ├── scraper.ts
    ├── parser.ts
    ├── formatter.ts
    └── ...

Server

server.ts creates the MCP server and registers every tool.

All six tools are registered in server.ts

Tools

Each file in tools/ is one tool plus its input schema. get_method_details, for example, takes a class name and a method name.

Scraper

src/lib/scraper.ts fetches the Javadoc pages. The base URL lives in the project config:

text
https://jd.papermc.io/paper/26.2/

So for now it's tied to that version of the docs.

Parser

It uses cheerio to read the HTML and pull out:

  • The class description
  • Method summary
  • Method details
  • Fields
  • Deprecated APIs

Formatter

Finally it all gets turned into Markdown, something like this:

markdown
# org.bukkit.entity.Player

## Signature

```java
public interface Player
```

## Description

...

## Method Summary

* `void sendMessage(...)`
* `boolean teleport(...)`

There's a cache too

Re-downloading the Javadocs for every single question would be painfully slow, so there's an in-memory cache. Ask about the same class or method again and it doesn't have to fetch it again.

Setting it up

You'll need:

  • Node.js
  • pnpm
  • An MCP client, like Claude Code, Claude Desktop, Cursor or Codex

Clone the repo:

bash
git clone https://github.com/FewPz/minedocs-mcp
cd minedocs-mcp

Install the dependencies and build:

bash
pnpm install
pnpm build

That gives you dist/server.js, which is what you point your client at.

Claude Code

Run this:

bash
claude mcp add minedocs -- node /absolute/path/to/minedocs-mcp/dist/server.js

Want it in every project? Add -s user:

bash
claude mcp add minedocs -s user -- node /absolute/path/to/minedocs-mcp/dist/server.js

Check that it's there:

bash
claude mcp list

Then start a new session and type /mcp. If you see minedocs, you're good to go.

Cursor or Claude Desktop

Add this to your MCP config:

json
{
  "mcpServers": {
    "minedocs": {
      "command": "node",
      "args": [
        "/absolute/path/to/minedocs-mcp/dist/server.js"
      ]
    }
  }
}

Then restart the client once.

No step-by-step instructions needed

This is my favourite part. Compared to pasting docs into the prompt yourself, you don't have to walk it through every step like:

text
Open this page
Find this class
Open this method
Read the parameters
Check if it's deprecated
Then write the code

You just say what you want:

text
Create a PaperMC plugin that gives a player
a custom message when they break a block.

It figures out which tools to use on its own. The flow ends up looking like this:

The AI checks the docs first, then writes the code

If you want to be extra sure

A short prompt usually works fine. But if you really want it to check the docs, just tell it to look things up first, like this:

text
Create a PaperMC plugin using the current API.

Before writing code:
1. Search PaperMC for the relevant classes.
2. Check the method signatures you plan to use.
3. Check whether those APIs are deprecated.
4. Only then generate the implementation.

The plugin should:
- listen for player block break events
- send a message to the player
- use modern Paper APIs where possible

Written like that, it'll go to the docs every time instead of rushing to write from memory.

It still makes mistakes, though

To be clear, even with MineDocs, the AI can still write bugs or make things up. It only helps with the API info not matching the version you're on.

Why it fits Minecraft so well

Minecraft has a lot of API. Player, World, Block, Entity, Event, Command, Inventory, Scheduler, Permission, Configuration, and plenty more. The bigger the project, the more the AI needs to know.

Stuffing the whole Javadocs into the prompt isn't realistic. The context fills up fast, and the AI has a harder time finding what it needs. Letting it ask for just the pages it needs works much better, and that's exactly what MCP is good at.

Where this could go

Hook up a few more MCP servers, like Git, build/test, or one that talks to a running Minecraft server, and the agent can do a lot more.

Dashed lines are the ones that don't exist yet

With all of that in place, it could loop on its own: write, build, test, fix any errors, and try again until it passes.

Keeps looping until it passes, then hands it over

At that point it starts to feel like a helper that can build most of a plugin end to end.

Wrapping up

MineDocs isn't trying to do everything. It just fixes the one problem I kept running into: giving AI an easy way to read the PaperMC Javadocs in a form it actually understands. It works with Claude Code, Claude Desktop, Cursor, or anything else that speaks MCP.

If you try it and get stuck, or there's a tool you'd like to see, open an issue on the repo and let's talk.

Links

Thanks for reading

Read more stories