# Mcp Annotated Java Sdk

> Build MCP servers in plain Java — with annotations, without Spring

- **Type:** MCP server
- **Install:** `agentstack add mcp-thought2code-mcp-annotated-java-sdk`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [thought2code](https://agentstack.voostack.com/s/thought2code)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [thought2code](https://github.com/thought2code)
- **Source:** https://github.com/thought2code/mcp-annotated-java-sdk
- **Website:** https://thought2code.github.io/mcp-annotated-java-sdk

## Install

```sh
agentstack add mcp-thought2code-mcp-annotated-java-sdk
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

English · [简体中文](README.zh-CN.md)

# [MCP Annotated Java SDK](https://github.com/thought2code/mcp-annotated-java-sdk)

*Annotation-driven MCP servers for lightweight Java applications.*

**A small, Spring-free annotation layer on top of the official MCP Java SDK.**

[Quick Start](#-quick-start) · [Why This SDK](#-why-this-sdk) · [Documentation](#-documentation) · [License](#-license)

[](https://central.sonatype.com/artifact/io.github.thought2code/mcp-annotated-java-sdk)
[](https://app.codecov.io/github/thought2code/mcp-annotated-java-sdk)
[](https://github.com/thought2code/mcp-annotated-java-sdk/actions/workflows/maven-build.yml)

---

## Overview

This SDK is a lightweight, annotation-based framework for building MCP servers in plain Java. Define MCP Resources / Prompts / Tools / Completions with ordinary Java methods, let the SDK generate the low-level MCP bindings, and run the server without bringing in Spring.

It is intentionally not a Spring AI replacement. Spring AI is the standard MCP entry point for Spring applications. This project focuses on the rest of the Java server space: CLI tools, embedded servers, local automation, small service processes, and teams that want annotation-driven MCP development without a Spring runtime.

> **Workflow:** Add dependency → Configure `mcp-server.yml` → Annotate Resources / Tools / Prompts / Completions → Run with `McpApplication`

[📖 Documentation](https://thought2code.github.io/mcp-annotated-java-sdk-docs) · [💡 Examples](https://github.com/thought2code/mcp-java-sdk-examples)

---

## ✨ Why This SDK?

### Positioning

| Project                                                                               | Best fit                                               | Role                         |
|---------------------------------------------------------------------------------------|--------------------------------------------------------|------------------------------|
| [Official MCP Java SDK](https://github.com/modelcontextprotocol/java-sdk)             | Library authors and low-level protocol integration     | Foundation                   |
| [Spring AI MCP](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html) | Spring Boot / Spring Framework applications            | Spring ecosystem standard    |
| **MCP Annotated Java SDK**                                                            | Plain Java, CLI, embedded, and lightweight MCP servers | Spring-free annotation layer |

**Rule of thumb:** Spring AI for Spring apps; MCP Annotated Java SDK for lightweight Java MCP servers without Spring.

### Key Advantages

- 🚫 **No Spring Framework Required** - Pure Java, lightweight and fast
- ⚡ **Instant MCP Server** - Get your server running with just 1 line of code
- 🎉 **Low Boilerplate** - No need to write repetitive low-level MCP SDK registration code
- 👏 **Generated JSON Schema** - Derive tool schemas from annotated Java signatures and metadata
- 🎯 **Focus on Logic** - Concentrate on your core business logic
- 🧩 **Compile-Time Binding Generation** - Annotation processing creates deterministic MCP component providers
- 🔌 **Spring AI-Friendly Configuration** - Familiar configuration shape for teams that may also use Spring AI
- 📦 **Type-Aware** - Leverage Java signatures and compile-time checks for safer MCP components

### Comparison

| Feature          | Official MCP Java SDK       | Spring AI MCP                  | This SDK                                   |
|------------------|-----------------------------|--------------------------------|--------------------------------------------|
| Primary audience | Low-level Java integrations | Spring applications            | Plain Java MCP servers                     |
| Spring required  | No                          | Yes, for Spring integration    | No                                         |
| Component model  | Programmatic registration   | Spring beans and annotations   | Plain classes and annotations              |
| JSON Schema      | Manual or app-provided      | Generated by Spring AI         | Generated by annotation processor          |
| Startup model    | You assemble the server     | Spring Boot auto-configuration | `McpApplication.run(...)`                  |
| Best use case    | Maximum control             | Enterprise Spring apps         | CLI, embedded, local tools, small services |

### Roadmap Focus

This project deliberately stays focused:

- Keep close compatibility with the official MCP Java SDK.
- Make plain Java MCP servers faster to write, test, and ship.
- Improve compile-time validation, generated bindings, schema support, and examples.
- Avoid competing with Spring AI on Boot auto-configuration, WebMVC/WebFlux integration, enterprise security, or observability.

## 🎯 Quick Start

### Prerequisites

- **Java 17 or later** (required by official MCP Java SDK)

### 5-Minutes Tutorial

#### Step 1: Add Dependency

**Maven:**
```xml

    io.github.thought2code
    mcp-annotated-java-sdk
    0.20.0

```

**Gradle:**
```gradle
implementation 'io.github.thought2code:mcp-annotated-java-sdk:0.20.0'
```

#### Step 2: Create Configuration File

Create `mcp-server.yml` in your `src/main/resources`:

```yaml
enabled: true
mode: STDIO
name: my-first-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
```

#### Step 3: Create Your MCP Server

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

#### Step 4: Define MCP Resources (if needed)

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

#### Step 5: Define MCP Tools

```java
public class MyTools {
    @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;
    }
}
```

#### Step 6: Define MCP Prompts (if needed)

```java
public class MyPrompts {
    @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);
    }
}
```

#### Step 7: Run Your Server

```bash
# Compile your project
./mvnw clean package
```

Run `MyFirstMcpServer` from your IDE, or use `java -cp ...` with your compiled classes and dependencies on the classpath. Your own project needs an executable JAR setup (for example Spring Boot or the Maven Shade plugin) if you want `java -jar` with a single file.

For deployment, build an executable fat JAR so runtime dependencies are included. If you use Maven Shade, configure the JAR manifest main class:

```xml

    org.apache.maven.plugins
    maven-shade-plugin
    3.6.2
    
        
            package
            
                shade
            
            
                false
                
                    
                        com.example.MyFirstMcpServer
                    
                
            
        
    

```

Keep `mcp-server.yml` in `src/main/resources` so it is packaged on the classpath.

That's it! Your MCP server is now ready to serve resources, tools, and prompts!

## 📚 Core Concepts

### What is MCP?

The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a standardized protocol for building servers that expose data and functionality to LLM applications. Think of it like a web API, but specifically designed for LLM interactions.

### MCP Components

| Component     | Purpose            | Analogy        |
|---------------|--------------------|----------------|
| **Resources** | Expose data to LLM | GET endpoints  |
| **Tools**     | Execute actions    | POST endpoints |
| **Prompts**   | Reusable templates | Form templates |

### Supported Server Modes

This SDK supports two MCP server modes:

| Mode           | Description                         | Use Case                                               |
|----------------|-------------------------------------|--------------------------------------------------------|
| **STDIO**      | Standard input/output communication | CLI tools, local development                           |
| **STREAMABLE** | HTTP streaming                      | Web applications, recommended for production           |

## 🔧 Advanced Usage

### Configuration File

Create `mcp-server.yml` in your classpath:

```yaml
enabled: true
mode: STREAMABLE
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
streamable:
  mcp-endpoint: /mcp/message
  disallow-delete: false
  keep-alive-interval: 20000
  port: 8080
```

### Configuration Properties

| Property                          | Description                                                     | Default                      |
|-----------------------------------|-----------------------------------------------------------------|------------------------------|
| `enabled`                         | Enable/disable MCP server                                       | `true`                       |
| `mode`                            | Server mode: `STDIO`, `STREAMABLE`                              | `STREAMABLE`                 |
| `name`                            | Server name                                                     | `mcp-server`                 |
| `version`                         | Server version                                                  | `1.0.0`                      |
| `type`                            | Server type: `SYNC`, `ASYNC`                                    | `SYNC`                       |
| `instructions`                    | Instructions for the LLM client                                 | Required (non-blank in YAML) |
| `request-timeout`                 | Request timeout in milliseconds                                 | `20000`                      |
| `capabilities.resource`           | Enable resource support                                         | `true`                       |
| `capabilities.subscribe-resource` | Enable resource subscription                                    | `true`                       |
| `capabilities.prompt`             | Enable prompt support                                           | `true`                       |
| `capabilities.tool`               | Enable tool support                                             | `true`                       |
| `capabilities.completion`         | Enable completion support                                       | `true`                       |
| `change-notification.resource`    | Notify clients on resource change                               | `true`                       |
| `change-notification.prompt`      | Notify clients on prompt change                                 | `true`                       |
| `change-notification.tool`        | Notify clients on tool change                                   | `true`                       |
| `streamable.mcp-endpoint`         | Streamable HTTP MCP path                                        | `/mcp/message`               |
| `streamable.disallow-delete`      | Reject HTTP DELETE on session                                   | `false`                      |
| `streamable.keep-alive-interval`  | Keep-alive interval (ms)                                        | `20000`                      |
| `streamable.port`                 | HTTP port for STREAMABLE mode                                   | `8080`                       |

### Profile-based Configuration

Set `profile` in the base file to load `mcp-server-{profile}.yml` from the classpath. Profile values are merged into the base configuration with Jackson deep merge; nested objects such as `capabilities` and `streamable` are merged field-by-field. The `profile` name always comes from the base file. After merge, transport settings that do not match the resolved `mode` are cleared (for example, `streamable` is removed when `mode` is `STDIO`).

You can use profiles for different environments:

```yaml
# mcp-server.yml (base configuration)
enabled: true
mode: STREAMABLE
name: my-mcp-server
version: 1.0.0
profile: dev
```

```yaml
# mcp-server-dev.yml (profile-specific configuration)
streamable:
  port: 8080
```

### Runtime model and stability

#### SYNC vs ASYNC (`type`)

The `type` setting selects which **MCP Java SDK server API** the framework uses. It does **not** turn your component methods into reactive code.

| `type`  | What happens                                                                                                                                                                            |
|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `SYNC`  | Handlers invoke your `@McpTool` / `@McpPrompt` / `@McpResource` methods on the request thread.                                                                                          |
| `ASYNC` | Handlers return Reactor `Mono` values for MCP SDK compatibility. The SDK wraps each call in `Mono.fromCallable(...)` — your method body is still a normal **blocking** Java invocation. |

**ASYNC is not a non-blocking or Project Reactor programming model.** You do not implement `Mono`/`Flux` in annotated methods. Long-running or CPU-heavy work still occupies a Reactor worker thread. Use **SYNC** unless your deployment specifically requires the async MCP server API. For high concurrency, keep handlers short and tune `request-timeout`.

#### Component instances and concurrency

The SDK creates **one instance per component class** (no-arg constructor) and reuses it for every MCP request to methods on that class. Concurrent calls share the same object.

- Prefer **stateless** component classes, or **thread-safe** mutable state only.
- Do not store per-request data in instance fields without proper synchronization.
- Delegate shared mutable state to thread-safe services when needed.

`McpApplicationContext.from(...)` currently uses this default singleton-per-class factory. Component classes must provide a **public no-arg constructor**. There is no built-in Spring/CDI wiring in the public API today.

`McpApplication.run(mainClass, args)` loads `mcp-server.yml` by default; pass a third argument to use another classpath config file name.

- **STREAMABLE** is the supported HTTP transport.

## 🏗️ Project Structure

A typical project structure:

```
your-mcp-project/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           ├── MyMcpServer.java         # Main entry point
│   │   │           ├── components/
│   │   │           │   ├── MyResources.java     # MCP Resources
│   │   │           │   ├── MyTools.java         # MCP Tools
│   │   │           │   └── MyPrompts.java       # MCP Prompts
│   │   │           └── ser

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [thought2code](https://github.com/thought2code)
- **Source:** [thought2code/mcp-annotated-java-sdk](https://github.com/thought2code/mcp-annotated-java-sdk)
- **License:** MIT
- **Homepage:** https://thought2code.github.io/mcp-annotated-java-sdk

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-thought2code-mcp-annotated-java-sdk
- Seller: https://agentstack.voostack.com/s/thought2code
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
