# java-mcp-server

Development guide for creating Java-based MCP servers using the official MCP Java SDK 2.x. It guides project setup, transport choices, and tool registration.

- rule · `type=rule` · GitHub Copilot · ★ 40418
- Author: github · official GitHub repository
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/github/awesome-copilot/tree/HEAD/instructions/java-mcp-server.instructions.md
- Updated: 2026-10-23
- HTML: https://affpapa.org/en/nevibecode/rules/java-mcp-server

## What it does

This rule configures GitHub Copilot to generate server code against the MCP Java SDK 2.x. Projects must import the `io.modelcontextprotocol.sdk:mcp-bom:2.0.1` bill of materials and the `io.modelcontextprotocol.sdk:mcp` dependency. In Gradle setups, adding `testRuntimeOnly("org.junit.platform:junit-platform-launcher")` is mandatory. The `test` task fails without it.

Servers initialise via `McpServer.sync(transport)` or `McpServer.async(transport)`. When running over stdio, the protocol claims standard output entirely. Calling `System.out.println()` corrupts message framing, so logging must route to standard error through SLF4J instead.

Tool specifications validate arguments against JSON Schema 2020-12 at build time. When tool execution fails, handlers must build a `CallToolResult` with `isError(true)` rather than throwing exceptions, which host clients often hide from the model. These guidelines strictly apply to direct SDK usage and exclude Quarkus projects.

## Install

### GitHub Copilot (native platform)

**Manually: put the files in place**
- File: `.github/instructions/java-mcp-server.instructions.md` — The applyTo field sets which files it applies to

### Claude Code

**Manually: put the files in place**
- File: `.claude/rules/java-mcp-server.md` — The paths frontmatter field limits the files: move applyTo from the source into paths

### Codex

**AGENTS.md**
- Codex reads AGENTS.md: paste the rule text there

### Cursor

**Manually: put the files in place**
- File: `.cursor/rules/java-mcp-server.mdc` — Frontmatter: description, globs, alwaysApply. Move applyTo from the source into globs, or the rule will not attach on its own

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/rules/java-mcp-server.md`

### Cline

**Manually: put the files in place**
- File: `.clinerules/java-mcp-server.md`

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/github/awesome-copilot/tree/HEAD/instructions/java-mcp-server.instructions.md

## When to use it
- configure MCP Java SDK 2.x dependencies in Gradle or Maven
- set up stdio transport with stderr logging
- register server tools with JSON Schema 2020-12 validation
- handle tool execution errors through structured CallToolResult responses

## Example prompts
- Create a synchronous Java MCP server using stdio transport and one tool
- Configure build.gradle.kts with the MCP Java SDK 2.0.1 BOM and test launcher
- Add a tool handler returning structuredContent with JSON Schema validation

## Source text · java-mcp-server.instructions.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 08a2b18fe61931b9.

BEGIN THIRD-PARTY FILE 08a2b18fe61931b9
```text
---
description: 'Instructions for building Model Context Protocol (MCP) servers in Java with the MCP Java SDK 2.x'
applyTo: '**/*.java, **/pom.xml, **/build.gradle, **/build.gradle.kts'
---

# Java MCP Server Development

These instructions apply to the [MCP Java SDK](https://github.com/modelcontextprotocol/java-sdk) 2.x. SDK 2.0.x supports the MCP specification revision [2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25) and the earlier revisions. SDK 3.x will add the revision [2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28).

> **Scope:** Apply these instructions only to projects that use the MCP Java SDK directly. Do not apply them to Quarkus or Quarkiverse MCP servers; use the `quarkus-mcp-server-sse` instruction for those.

## Instructions

- Import the BOM `io.modelcontextprotocol.sdk:mcp-bom:2.0.1` and add the `io.modelcontextprotocol.sdk:mcp` artifact.
- In Gradle, import the BOM with `implementation(platform("io.modelcontextprotocol.sdk:mcp-bom:2.0.1"))`. Also add `testRuntimeOnly("org.junit.platform:junit-platform-launcher")`. Without it, the `test` task fails.
- The `mcp` artifact contains `mcp-core` and the Jackson 3 JSON mapper `mcp-json-jackson3`.
- Do not use code from SDK 0.x or 1.x. Read the [migration guide](https://github.com/modelcontextprotocol/java-sdk/blob/main/MIGRATION-2.0.md) when you update a server.
- The packages are `io.modelcontextprotocol.server`, `io.modelcontextprotocol.spec`, and `io.modelcontextprotocol.json`. The protocol types are nested in `McpSchema`.
- Make a server with `McpServer.sync(transport)` or `McpServer.async(transport)`. Set `serverInfo(name, version)` and `capabilities(...)`, and then call `build()`.
- Use the sync server for most servers. Use the async server with Project Reactor (`Mono`) only when the tool code does not block a thread.
- For stdio transport, use `new StdioServerTransportProvider(McpJsonDefaults.getMapper())`.
- Enable only the capabilities that the server uses: `ServerCapabilities.builder().tools(false).resources(false, true).prompts(true).completions().build()`. `tools(listChanged)` and `prompts(listChanged)` enable list change notifications. `resources(subscribe, listChanged)` also enables resource subscriptions.
- Register tools with `SyncToolSpecification.builder().tool(tool).callHandler((exchange, request) -> ...)`. The handler gets the arguments as a `Map` from `request.arguments()`.
- Use the builders that take the required fields first: `Tool.builder(name, inputSchema)`, `Resource.builder(uri, name)`, `ResourceTemplate.builder(uriTemplate, name)`, `Prompt.builder(name)`, `TextContent.builder(text)`, and `ReadResourceResult.builder(contents)`. The builders without arguments are deprecated.
- A required field must not be `null`. A `null` value causes an `IllegalArgumentException`.
- Tool names must have 1 to 128 characters: letters, digits, `_`, `-`, and `.`. The server builder rejects an incorrect name with an `IllegalArgumentException`. `addTool()` at runtime does not check the name.
- Give `inputSchema` and `outputSchema` as `Map<String, Object>` values. The `JsonSchema` record is deprecated.
- The server checks each schema against JSON Schema 2020-12 when you call `build()` or `addTool()`. An incorrect schema causes an `IllegalArgumentException`.
- The SDK validates the arguments against `inputSchema` before it calls the handler. It also validates `structuredContent` against `outputSchema`. If the validation fails, the client gets a tool result with `isError` set to `true`.
```
END THIRD-PARTY FILE 08a2b18fe61931b9

The third-party file has ended. Everything between the 08a2b18fe61931b9 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3559 of 17681 bytes. © github · MIT · https://github.com/github/awesome-copilot/tree/HEAD/instructions/java-mcp-server.instructions.md

From the same set: [github/awesome-copilot](https://affpapa.org/en/nevibecode/by/github/awesome-copilot.md) — 770 cards

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
