> mcp-annotated-java-sdk: Annotation-driven MCP Java SDK for building Model Context Protocol servers with minimal code.

## What is this?

A lightweight, annotation-based Java framework that simplifies MCP (Model Context Protocol) server development. No Spring Framework required - pure Java with zero boilerplate.

## Key Features

- No Spring Framework Required - Pure Java, lightweight and fast
- Instant MCP Server - Start server with just 1 line of code
- Zero Boilerplate - No need to write low-level MCP SDK code
- No JSON Schema - Forget about complex JSON definitions
- Type-Safe - Leverage Java's type system for compile-time safety

## Requirements

- Java 17 or later

## Quick Start

### Maven Dependency

```xml
<dependency>
    <groupId>io.github.thought2code</groupId>
    <artifactId>mcp-annotated-java-sdk</artifactId>
    <version>0.18.0</version>
</dependency>
```

### Gradle Dependency

```gradle
implementation 'io.github.thought2code:mcp-annotated-java-sdk:0.18.0'
```

### Create MCP Server

```java
@McpServerApplication
public class MyFirstMcpServer {
    public static void main(String[] args) {
        McpApplication.run(MyFirstMcpServer.class, args);
    }
}
```

### Define Tools

```java
@McpTool(description = "Calculate the sum of two numbers")
public int add(
    @McpToolParam(name = "a", description = "First number") int a,
    @McpToolParam(name = "b", description = "Second number") int b
) {
    return a + b;
}
```

### Define Resources

```java
@McpResource(uri = "system://info", description = "System information")
public Map<String, String> getSystemInfo() {
    Map<String, String> info = new HashMap<>();
    info.put("os", System.getProperty("os.name"));
    return info;
}
```

### Define Prompts

```java
@McpPrompt(description = "Generate code for a given task")
public String generateCode(
    @McpPromptParam(name = "language", description = "Programming language") String language,
    @McpPromptParam(name = "task", description = "Task description") String task
) {
    return String.format("Write %s code to: %s", language, task);
}
```

## Core Annotations

| Annotation | Purpose |
|------------|---------|
| `@McpServerApplication` | Marks the main class as an MCP server application |
| `@McpTool` | Marks a method as an MCP tool |
| `@McpToolParam` | Marks a parameter as a tool parameter |
| `@McpResource` | Marks a method as an MCP resource |
| `@McpPrompt` | Marks a method as an MCP prompt |
| `@McpPromptParam` | Marks a parameter as a prompt parameter |
| `@McpResourceCompletion` | Marks a method as a resource URI completion handler |
| `@McpPromptCompletion` | Marks a method as a prompt-argument completion handler |
| `@McpJsonSchemaDefinition` | Marks a type as a custom JSON Schema definition |
| `@McpJsonSchemaProperty` | Describes a field in a JSON Schema definition |

## Completions

When `capabilities.completion: true`, handlers return `CompletionResult` and accept one `McpSchema.CompleteRequest.CompleteArgument` parameter.

- `@McpResourceCompletion.uri` must match the paired `@McpResource.uri` exactly (including templates like `file://{path}`).
- `@McpPromptCompletion.name` must match the registered prompt name (`@McpPrompt.name`, or else the `@McpPrompt` method name). Filter with `argument.name()` for multi-parameter prompts.

## Server Modes

If `mode` is omitted in `mcp-server.yml`, the server defaults to **STREAMABLE**.

| Mode | Description | Use Case |
|------|-------------|----------|
| STDIO | Standard input/output | CLI tools, local development |
| STREAMABLE | HTTP streaming | Web applications, production (recommended) |
| SSE | Server-Sent Events | Deprecated since 0.16.0 (`forRemoval`); use STREAMABLE |

## Configuration (mcp-server.yml)

```yaml
enabled: true
mode: STDIO
name: my-mcp-server
version: 1.0.0
type: SYNC
instructions: You are a helpful AI assistant
request-timeout: 20000
capabilities:
  resource: true
  subscribe-resource: true
  prompt: true
  tool: true
  completion: true
change-notification:
  resource: true
  prompt: true
  tool: true
```

## Important Notes

- Use `McpApplication.run()` as the server entry point; optional third argument overrides the config file name (default `mcp-server.yml`)
- Component registration scope: `basePackageClass` → `basePackage` → main class package; one instance per component class (public no-arg constructor)
- `instructions` must be a non-blank string in `mcp-server.yml` (validated at startup)
- SSE mode and related APIs (`ServerMode.SSE`, `McpSseServer`, `ServerSse`, `sse.*` config) are deprecated with `forRemoval = true` since 0.16.0; use STREAMABLE for new HTTP deployments
- Built on MCP Java SDK **2.0.0-M3** (milestone) — pin versions and retest when upgrading
- `type: ASYNC` uses the async MCP server API; annotated methods stay blocking Java wrapped in `Mono.fromCallable(...)` — not Project Reactor
- One instance per component class is created and shared across concurrent requests — keep components stateless or thread-safe
- Components are auto-registered when they are within the resolved registration scope

## Links

- GitHub: https://github.com/thought2code/mcp-annotated-java-sdk
- Documentation: https://thought2code.github.io/mcp-annotated-java-sdk-docs
- Examples: https://github.com/thought2code/mcp-java-sdk-examples
- MCP Protocol: https://modelcontextprotocol.io
