This project demonstrates how to build a simple Spring Boot API and expose it as both REST endpoints and Model Context Protocol (MCP) tools using Spring Boot and Spring AI MCP Server. The app now includes a UserService
that is exposed as an MCP tool.
- Features
- Requirements
- Setup
- Running the Application
- REST API Usage
- MCP Server Usage (SSE + JSON-RPC)
- Testing
- Development Notes
- Troubleshooting
- UserService tool: get user details by user ID (REST and MCP)
- REST API endpoint for user details
- MCP server exposes user service as AI tool (usable by VS Code Copilot, etc.)
- Full test coverage with integration tests
- Java 17+
- Maven 3.8+
- VS Code (optional, for MCP client testing)
- REST Client extension (optional, for
.http
files)
- Clone the repository:
git clone <your-repo-url> cd mcpdemo
- Configure Git (optional):
git config user.name "<your-username>" git config user.email "<your-email>"
- Build the project:
./mvnw clean install
Start the Spring Boot application:
./mvnw spring-boot:run
The server will start on http://localhost:8080.
You can test the user endpoint using curl, Postman, or the provided .http
file.
- Get user details:
Response:
GET http://localhost:8080/api/users/123
"User: 123, Name: John Doe"
The MCP server uses Server-Sent Events (SSE) for session-based communication and JSON-RPC over HTTP for sending messages. This allows you to receive asynchronous responses in a browser or SSE client while sending requests via POST.
Open your browser and navigate to:
http://localhost:8080/mcp/sse
A new session will be created and you will receive a response like:
id:8a09a074-ad2d-434d-a768-8e30f25a186b
event:endpoint
data:/mcp/messages?sessionId=8a09a074-ad2d-434d-a768-8e30f25a186b
- The
id
is your session ID. - The
data
field gives you the correct messages endpoint for this session.
Use a tool like Bruno, Postman, or curl to send POST requests to:
http://localhost:8080/mcp/messages?sessionId=<your-session-id>
with a JSON body. For example, to initialize:
{
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "warp",
"version": "1.0.0"
}
}
}
Then send:
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
You can now send tool/list or tool/invoke requests as shown below. All responses will appear in the browser window (SSE session) you opened in step 1.
{
"jsonrpc": "2.0",
"id": "2",
"method": "tools/list",
"params": {}
}
{
"jsonrpc": "2.0",
"id": "3",
"method": "tools/call",
"params": {
"name": "getUserDetailsMcp",
"arguments": {
"userId": "123"
}
}
}
{
"jsonrpc": "2.0",
"id": "3",
"result": "User: 123, Name: John Doe"
}
- Open VS Code and install an MCP-compatible extension (e.g., Copilot Chat).
- Set the MCP server URL to
http://localhost:8080/mcp/sse
in the extension settings. - Use the extension's chat or tool features to call your user tool.
Run all tests with:
./mvnw test
All endpoints and MCP tools are covered by integration tests.
- User logic is in
UserService
. - REST endpoint is in
UserController
. - MCP tool registration is in
McpConfig
. - MCP server configuration is in
src/main/resources/application.yaml
.
- SessionId error: Always include a
sessionId
in MCP tool/completion requests. - Tool not visible in VS Code: Ensure the MCP server is running and the extension is pointed to the correct URL.
- Port conflicts: Change the port in
application.yaml
if needed. - Logs: Enable TRACE logging in
application.yaml
for detailed MCP server logs.