fastMCP4J
Fast lightweight Java MCP server framework - Build Model Context Protocol servers with minimal boilerplate and full TypeScript SDK compatibility
FastMCP4J
Java library for building MCP servers — annotation-driven, minimal dependencies
AI Agents → Share this skill with Claude for code generation
Lightweight. 12 dependencies. No containers.
Just annotate and run. See below →
Note: Beta release (v0.3.1-beta) — Multi-class modules, bash tools, telemetry. API stable.
Quick Start (2 minutes)
Add dependency
Maven:
<dependency>
<groupId>io.github.terseprompts.fastmcp</groupId>
<artifactId>fastmcp-java</artifactId>
<version>0.3.1-beta</version>
</dependency>
Gradle:
dependencies {
implementation 'io.github.terseprompts.fastmcp:fastmcp-java:0.3.1-beta'
}
Create your server
@McpServer(name = "Assistant", version = "1.0")
public class MyAssistant {
@McpTool(description = "Summarize text")
public String summarize(@McpParam(description = "Text") String text) {
return "Summary: " + text.substring(0, Math.min(100, text.length()));
}
public static void main(String[] args) {
FastMCP.server(MyAssistant.class)
.stdio() // or .sse() or .streamable()
.run();
}
}
Run it
mvn exec:java -Dexec.mainClass="com.example.MyAssistant"
That's it. Your MCP server is running.
Working example: EchoServer.java
Who This Is For
| You want to... | FastMCP4J |
|---|---|
| Expose Java tools to AI agents | ✅ Perfect fit |
| Build MCP servers quickly | ✅ Annotation-driven, minimal code |
| Add MCP to existing Spring app | ✅ Drop-in, no framework lock-in |
| Lightweight MCP-only solution | ✅ 12 dependencies, not 50+ |
| Fast startup & low memory | ✅ <500ms cold start, ~64MB |
How to Use
Make a tool
@McpTool(description = "Add two numbers")
public int add(int a, int b) {
return a + b;
}
Make it async
@McpTool(description = "Process data")
@McpAsync // ← just add this
public Mono<String> process(@McpContext Context ctx, String input) {
return Mono.fromCallable(() -> {
ctx.reportProgress(50, "Processing...");
return slowOperation(input);
});
}
Add memory
@McpServer(name = "MyServer", version = "1.0")
@McpMemory // ← just add this
public class MyServer {
// AI now remembers things across sessions
}
Add all built-in tools
@McpServer(name = "MyServer", version = "1.0")
@McpMemory // AI remembers
@McpTodo // AI manages tasks
@McpPlanner // AI breaks tasks into steps
@McpFileRead // AI reads your files
@McpFileWrite // AI writes files
public class MyServer {
// All tools enabled, zero implementation needed
}
Organize tools across multiple classes
@McpServer(
name = "MyServer",
version = "1.0",
modules = {StringTools.class, MathTools.class} // Explicit modules
)
public class MyServer {
// Tools from StringTools and MathTools are included
}
Or use package scanning for auto-discovery:
@McpServer(
name = "MyServer",
version = "1.0",
scanBasePackage = "com.example.tools" // Auto-discover all tools
)
public class MyServer {
// All @McpTool classes in the package are included
}
Add bash/shell execution
@McpServer(name = "MyServer", version = "1.0")
@McpBash(timeout = 30) // Shell command execution with security guardrails
public class MyServer {
// Provides 'execute_command' tool with OS-aware shell selection
}
Add telemetry
@McpServer(name = "MyServer", version = "1.0")
@McpTelemetry(enabled = true, exportConsole = true) // Metrics & tracing
public class MyServer {
// Automatic tool invocation tracking with console export
}
Choose transport
FastMCP.server(MyServer.class)
.stdio() // For CLI tools, local agents
.sse() // For web clients, long-lived connections
.streamable() // For bidirectional streaming (recommended)
.run();
Configure port, timeout, capabilities
FastMCP.server(MyServer.class)
.port(3000) // HTTP port
.requestTimeout(Duration.ofMinutes(5)) // Request timeout
.keepAliveSeconds(30) // Keep-alive interval
.capabilities(c -> c
.tools(true)
.resources(true, true)
.prompts(true))
.run();
Icons
Add visual polish to your server, tools, resources, and prompts.
@McpServer(
name = "my-server",
icons = {
"data:image/svg+xml;base64,...:image/svg+xml:64x64:light",
"data:image/svg+xml;base64,...:image/svg+xml:64x64:dark"
}
)
@McpTool(
description = "My tool",
icons = {"https://example.com/icon.png"}
)
public class MyServer { }
Resources & Prompts
@McpResource(uri = "config://settings")
public String getSettings() {
return "{\"theme\": \"dark\"}";
}
@McpPrompt(name = "code-review")
public String codeReviewPrompt(@McpParam(description = "Code to review") String code) {
return "Review this code:\n" + code;
}
Built-in Tools
Add ONE annotation, get complete functionality.
| Annotation | Tools You Get |
|---|---|
@McpMemory | list, read, create, replace, insert, delete, rename |
@McpTodo | add, list, updateStatus, updateTask, delete, clearCompleted |
@McpPlanner | createPlan, listPlans, getPlan, addTask, addSubtask |
@McpFileRead | readLines, readFile, grep, getStats |
@McpFileWrite | writeFile, appendFile, writeLines, deleteFile, createDirectory |
Annotations Reference
| Annotation | Target | Purpose |
|---|---|---|
@McpServer | TYPE | Define your MCP server |
@McpTool | METHOD | Expose as callable tool |
@McpResource | METHOD | Expose as resource |
@McpPrompt | METHOD | Expose as prompt template |
@McpParam | PARAMETER | Add description, examples, constraints, defaults |
@McpAsync | METHOD | Make tool async (return Mono<?>) |
@McpContext | PARAMETER | Inject request context |
@McpPreHook | METHOD | Run before tool call (params: toolName, order) |
@McpPostHook | METHOD | Run after tool call (params: toolName, order) |
@McpBash | TYPE | Enable bash/shell command execution tool |
@McpTelemetry | TYPE | Enable metrics and tracing (params: enabled, exportConsole, exportOtlp, sampleRate) |
@McpMemory | TYPE | Enable memory tools |
@McpTodo | TYPE | Enable todo/task management tools |
@McpPlanner | TYPE | Enable planning tools |
@McpFileRead | TYPE | Enable file reading tools |
@McpFileWrite | TYPE | Enable file writing tools |
@McpParam advanced options:
@McpTool(description = "Create task")
public String createTask(
@McpParam(
description = "Task name",
examples = {"backup", "sync"},
constraints = "Cannot be empty",
defaultValue = "default",
required = false
) String taskName
) { return "Created: " + taskName; }
Hooks — Run Code Before/After Tools
Two hook types supported:
@McpPreHook — Runs before tool is called. Receives Map<String, Object> arguments.
@McpPostHook — Runs after tool completes. Receives Map<String, Object> arguments, Object result.
Use for logging, validation, authentication, audit trails, metrics.
@McpServer(name = "MyServer", version = "1.0")
public class MyServer {
@McpTool(description = "Calculate")
public int calculate(int x, int y) {
return x + y;
}
// Run before ALL tools (*)
@McpPreHook(toolName = "*", order = 1)
void authenticate(Map<String, Object> args) {
String token = (String) args.get("token");
if (!isValid(token)) throw new SecurityException("Unauthorized");
}
// Run after specific tool only
@McpPostHook(toolName = "calculate", order = 1)
void logResult(Map<String, Object> args, Object result) {
System.out.println("Result: " + result);
}
public static void main(String[] args) {
FastMCP.server(MyServer.class).stdio().run();
}
}
Hook options:
toolName— Target specific tool name, or"*"for all tools. Empty = inferred from method nameorder— Execution priority (lower = first). Default:0
Hook parameters:
- Pre-hook:
Map<String, Object> arguments— Tool input arguments - Post-hook:
Map<String, Object> arguments, Object result— Input + output
Context Access — Request Metadata
@McpContext — Inject request context into your tool.
Access client info, session data, request metadata.
@McpServer(name = "MyServer", version = "1.0")
public class MyServer {
@McpTool(description = "Get client info")
public String getClientInfo(@McpContext Context context) {
return "Client: " + context.getClientId();
}
@McpTool(description = "Get session ID")
public String getSessionId(@McpContext Context context) {
return "Session: " + context.getSessionId();
}
@McpTool(description = "Read file with context")
public String readFile(@McpContext Context context, String path) {
context.info("Reading file: " + path);
// Access request headers (e.g., for auth)
Map<String, String> headers = context.getRequestHeaders();
String authHeader = headers.get("Authorization");
// ... read file
return "Content";
}
public static void main(String[] args) {
FastMCP.server(MyServer.class).stdio().run();
}
}
Context capabilities:
getClientId()— Client identifiergetSessionId()— Session identifiergetToolName()— Current tool namegetRequestHeaders()— Client request headers (e.g., auth tokens, custom headers)info(String)— Log info messagewarning(String)— Log warningerror(String)— Log errorreportProgress(int, String)— Report progress percentagelistResources()— List available resourceslistPrompts()— List available prompts
New Features
@McpBash — Shell Command Execution
Execute shell commands with OS-aware shell selection and built-in security guardrails.
@McpServer(name = "MyServer", version = "1.0")
@McpBash(
timeout = 30, // Command timeout in seconds
visibleAfterBasePath = "/sandbox/*", // Whitelist allowed directories
notAllowedPaths = {"/etc", "/root"} // Blacklist dangerous paths
)
public class MyServer { }
Security features:
- Directory validation (whitelist/blacklist)
- Dangerous command blocking (rm -rf, wget, curl, ssh, etc.)
- Directory traversal prevention
- Cross-platform path handling (Windows/Unix)
Supported shells:
- Windows:
cmd.exe - macOS:
/bin/zsh - Linux:
/bin/bash
@McpTelemetry — Metrics & Tracing
Collect metrics and traces for tool invocations.
@McpServer(name = "MyServer", version = "1.0")
@McpTelemetry(
enabled = true,
exportConsole = true, // Human-readable output
exportOtlp = false, // OpenTelemetry export
sampleRate = 1.0, // 100% sampling
includeArguments = false, // Don't log sensitive args
metricExportIntervalMs = 60_000
)
public class MyServer { }
Collected metrics:
- Tool invocation counters
- Execution duration histograms
- Error rates
Multi-Class Tool Organization
Split tools across multiple classes for better organization.
Manual modules (fast, explicit):
@McpServer(
name = "MyServer",
version = "1.0",
modules = {StringTools.class, MathTools.class}
)
Package scanning (convenient):
@McpServer(
name = "MyServer",
version = "1.0",
scanBasePackage = "com.example.tools"
)
Why FastMCP4J?
Less code
Raw MCP SDK: 35+ lines per tool FastMCP4J: ~8 lines per tool
Lightweight
| Framework | Dependencies | Best For |
|---|---|---|
| Spring AI | 50+ jars | Full-stack AI apps |
| LangChain4j | 30+ jars | Enterprise AI pipelines |
| Quarkus AI | 40+ jars | Cloud-native microservices |
| FastMCP4J | 12 jars | MCP servers only |
Fast & focused
- Cold start: <500ms
- Tool invocation: <5ms
- Memory: ~64MB
- Purpose-built for MCP — not a general AI framework
Documentation
- Architecture — How it works
- Roadmap — What's next
- Contributing — PRs welcome
- Changelog — Version history
- Claude Skill — For AI agents
License
MIT © 2026
Less boilerplate. More shipping.
Get started • Examples • Docs
Made with ❤️ for the Java community
Related Servers
Scout Monitoring MCP
sponsorPut performance and error data directly in the hands of your AI assistant.
Alpha Vantage MCP Server
sponsorAccess financial market data: realtime & historical stock, ETF, options, forex, crypto, commodities, fundamentals, technical indicators, & more
Accordo MCP Server
Provides dynamic YAML-driven workflow guidance for AI coding agents with structured development workflows, progression control, and decision points.
Django MCP Server
A Django extension to enable AI agents to interact with Django apps through the Model Context Protocol.
Rug-Check-MCP
Detects potential risks in Solana meme tokens to help avoid rug pulls and unsafe projects.
MCP Time Server
Provides tools for getting the current time and date, and formatting timestamps in various formats and timezones.
MCP Mermaid Server
Generate and analyze Mermaid diagrams.
PentestGPT-MCP
An advanced penetration testing tool for automated, LLM-driven security assessments using tools like nmap and dirb.
QuickChart Server
Generate chart images and URLs using the QuickChart.io API with Chart.js configurations.
Nuxt MCP
MCP server helping models to understand your Vite/Nuxt app better.
Gentoro
Gentoro generates MCP Servers based on OpenAPI specifications.
Windows Command Line MCP Server
Enables AI models to interact with the Windows command-line safely and efficiently.