- Notifications
You must be signed in to change notification settings - Fork 1
MCP Client Example #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hamzausmani wants to merge 1 commit into spring-ai-community:main Choose a base branch from hamzausmani:feature/mcp-client-example
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline, and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| FROM --platform=linux/arm64 amazoncorretto:21-alpine | ||
| | ||
| # Install Python and uv for MCP server support | ||
| RUN apk add --no-cache python3 py3-pip curl bash wget | ||
| | ||
| # Install uv (Python package manager) | ||
| RUN curl -LsSf https://astral.sh/uv/install.sh | sh | ||
| ENV PATH="/root/.local/bin:${PATH}" | ||
| | ||
| # Verify uvx is available | ||
| RUN uvx --version | ||
| | ||
| WORKDIR /app | ||
| | ||
| # Copy the application JAR | ||
| COPY target/*.jar app.jar | ||
| | ||
| # Expose port | ||
| EXPOSE 8080 | ||
| | ||
| # Health check | ||
| HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ | ||
| CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ping || exit 1 | ||
| | ||
| # Run the application | ||
| ENTRYPOINT ["java", "-jar", "app.jar"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,236 @@ | ||
| # Spring AI MCP Client Agent | ||
| | ||
| A Spring Boot application demonstrating integration with Model Context Protocol (MCP) servers. This example connects to the AWS Documentation MCP Server over stdio to provide AI-powered AWS documentation assistance. | ||
| | ||
| ## Features | ||
| | ||
| - **MCP Client Integration**: Connects to MCP servers over stdio transport | ||
| - **AWS Documentation Tools**: | ||
| - Search AWS documentation | ||
| - Read full documentation pages | ||
| - Get related documentation recommendations | ||
| - **AgentCore Integration**: Uses `@AgentCoreInvocation` for automatic endpoint setup | ||
| - **Amazon Bedrock**: Integration with Claude 3 Sonnet model | ||
| - **Tool Wrapping**: Wraps MCP server tools as Spring AI tools | ||
| | ||
| ## Prerequisites | ||
| | ||
| - Java 21 | ||
| - Maven | ||
| - AWS account with access to Amazon Bedrock | ||
| - AWS credentials configured locally | ||
| - Python with `uv` and `uvx` installed (for MCP server) | ||
| | ||
| ### Installing uv/uvx | ||
| | ||
| The MCP server runs via `uvx`, which requires `uv` to be installed: | ||
| | ||
| **macOS/Linux:** | ||
| ```bash | ||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||
| ``` | ||
| | ||
| **Or with Homebrew:** | ||
| ```bash | ||
| brew install uv | ||
| ``` | ||
| | ||
| **Or with pip:** | ||
| ```bash | ||
| pip install uv | ||
| ``` | ||
| | ||
| After installation, `uvx` will be available automatically. | ||
| | ||
| ## Architecture | ||
| | ||
| ``` | ||
| ┌─────────────────────────────────────────────────────────────┐ | ||
| │ Spring Boot Application │ | ||
| │ │ | ||
| │ ┌──────────────┐ ┌─────────────────┐ │ | ||
| │ │ ChatClient │─────▶│ AwsDocsMcpTools │ │ | ||
| │ │ (Spring AI) │ │ (Tool Wrapper) │ │ | ||
| │ └──────────────┘ └────────┬────────┘ │ | ||
| │ │ │ | ||
| │ ┌────────▼────────┐ │ | ||
| │ │ McpStdioClient │ │ | ||
| │ │ (MCP Client) │ │ | ||
| │ └────────┬────────┘ │ | ||
| └──────────────────────────────────┼──────────────────────────┘ | ||
| │ stdio | ||
| ┌─────────▼──────────┐ | ||
| │ uvx process │ | ||
| │ AWS Docs MCP │ | ||
| │ Server │ | ||
| └────────────────────┘ | ||
| ``` | ||
| | ||
| ## Configuration | ||
| | ||
| The MCP client connects to the AWS Documentation server with these settings: | ||
| | ||
| ```java | ||
| command: "uvx" | ||
| args: ["awslabs.aws-documentation-mcp-server@latest"] | ||
| env: | ||
| FASTMCP_LOG_LEVEL: "ERROR" | ||
| AWS_DOCUMENTATION_PARTITION: "aws" | ||
| ``` | ||
| | ||
| ## Building and Running | ||
| | ||
| ```bash | ||
| mvn clean package | ||
| java -jar target/mcp-client-agent-0.0.1-SNAPSHOT.jar | ||
| ``` | ||
| | ||
| Or use Maven directly: | ||
| | ||
| ```bash | ||
| mvn spring-boot:run | ||
| ``` | ||
| | ||
| The application starts on port 8080. | ||
| | ||
| ## API Endpoints | ||
| | ||
| ### AWS Documentation Query Endpoint | ||
| | ||
| ```bash | ||
| # Ask about AWS services | ||
| curl -X POST http://localhost:8080/invocations \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"prompt":"What is Amazon S3?"}' | ||
| | ||
| # Ask about specific features | ||
| curl -X POST http://localhost:8080/invocations \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"prompt":"How do I configure S3 bucket versioning?"}' | ||
| | ||
| # Ask about best practices | ||
| curl -X POST http://localhost:8080/invocations \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"prompt":"What are the best practices for Lambda function configuration?"}' | ||
| | ||
| # Compare services | ||
| curl -X POST http://localhost:8080/invocations \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"prompt":"What is the difference between ECS and EKS?"}' | ||
| ``` | ||
| | ||
| ### Health Endpoints | ||
| | ||
| ```bash | ||
| # AgentCore health check | ||
| curl http://localhost:8080/ping | ||
| | ||
| # Actuator health check | ||
| curl http://localhost:8080/actuator/health | ||
| ``` | ||
| | ||
| ## How It Works | ||
| | ||
| 1. **MCP Client Initialization**: On startup, `McpStdioClient` connects to the AWS Documentation MCP server via stdio | ||
| 2. **Tool Discovery**: The client lists available tools from the MCP server | ||
| 3. **Tool Wrapping**: `AwsDocsMcpTools` wraps MCP tools as Spring AI `@Tool` methods | ||
| 4. **AI Processing**: When a user asks about AWS: | ||
| - The AI model analyzes the query | ||
| - Determines which MCP tool(s) to call | ||
| - Calls the tools via the MCP client | ||
| - Synthesizes a response with documentation | ||
| | ||
| ## Available MCP Tools | ||
| | ||
| ### search_documentation | ||
| Search AWS documentation for specific topics. | ||
| | ||
| **Parameters:** | ||
| - `search_phrase` (required): Search query | ||
| - `limit` (optional): Max results (default: 5) | ||
| | ||
| ### read_documentation | ||
| Read full content of an AWS documentation page. | ||
| | ||
| **Parameters:** | ||
| - `url` (required): Documentation URL | ||
| - `max_length` (optional): Max content length (default: 5000) | ||
| - `start_index` (optional): Starting position (default: 0) | ||
| | ||
| ### recommend | ||
| Get related documentation recommendations. | ||
| | ||
| **Parameters:** | ||
| - `url` (required): Documentation URL to get recommendations for | ||
| | ||
| ## Example Interactions | ||
| | ||
| **User**: "What is Amazon S3?" | ||
| **Agent**: Searches AWS docs, reads relevant pages, provides comprehensive answer with links | ||
| | ||
| **User**: "How do I enable S3 versioning?" | ||
| **Agent**: Searches for versioning docs, reads the guide, provides step-by-step instructions | ||
| | ||
| **User**: "What's the difference between ECS and EKS?" | ||
| **Agent**: Searches for both services, compares features, provides clear explanation | ||
| | ||
| ## Project Structure | ||
| | ||
| ``` | ||
| src/main/java/com/unicorn/mcp/ | ||
| ├── McpClientApplication.java # Main application | ||
| ├── McpController.java # AgentCore controller | ||
| ├── McpStdioClient.java # MCP client (stdio transport) | ||
| ├── AwsDocsMcpTools.java # Tool wrappers for Spring AI | ||
| └── PromptRequest.java # Request model | ||
| ``` | ||
| | ||
| ## Troubleshooting | ||
| | ||
| ### MCP Server Connection Issues | ||
| | ||
| If the MCP server fails to start: | ||
| | ||
| 1. Verify `uvx` is installed: `uvx --version` | ||
| 2. Test the MCP server manually: | ||
| ```bash | ||
| uvx awslabs.aws-documentation-mcp-server@latest | ||
| ``` | ||
| 3. Check logs in the application output | ||
| | ||
| ### Tool Call Failures | ||
| | ||
| If tools fail to execute: | ||
| - Check the MCP server logs (set `FASTMCP_LOG_LEVEL=DEBUG`) | ||
| - Verify the tool arguments match the expected schema | ||
| - Ensure network connectivity for documentation fetching | ||
| | ||
| ## Deployment to AWS | ||
| | ||
| This example can be deployed to Amazon Bedrock AgentCore Runtime. See: | ||
| | ||
| - **[QUICKSTART.md](QUICKSTART.md)** - 5-minute deployment guide | ||
| - **[DEPLOYMENT.md](DEPLOYMENT.md)** - Comprehensive deployment documentation | ||
| | ||
| Quick deploy: | ||
| | ||
| ```bash | ||
| ./deploy.sh | ||
| ``` | ||
| | ||
| Or manually: | ||
| | ||
| ```bash | ||
| cd ../terraform | ||
| ./build-and-push.sh spring-ai-mcp-client | ||
| terraform apply | ||
| ./invoke-iam.sh "test" "What is Amazon S3?" | ||
| ``` | ||
| | ||
| ## Notes | ||
| | ||
| - The MCP server is started automatically by the Java application | ||
| - The stdio transport provides reliable communication between Java and Python | ||
| - Tool calls are synchronous and may take a few seconds for documentation fetching | ||
| - The AI model automatically determines when to use MCP tools vs. its own knowledge | ||
| - The container includes Python and uv for running MCP servers |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <parent> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-parent</artifactId> | ||
| <version>3.4.5</version> | ||
| <relativePath/> | ||
| </parent> | ||
| <groupId>com.unicorn</groupId> | ||
| <artifactId>mcp-client-agent</artifactId> | ||
| <version>0.0.1-SNAPSHOT</version> | ||
| <name>mcp-client-agent</name> | ||
| <description>Spring AI Agent with MCP Client for AWS Documentation</description> | ||
| <properties> | ||
| <java.version>21</java.version> | ||
| <spring-ai.version>1.0.0</spring-ai.version> | ||
| </properties> | ||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.springframework.ai</groupId> | ||
| <artifactId>spring-ai-starter-model-bedrock-converse</artifactId> | ||
| </dependency> | ||
| | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-actuator</artifactId> | ||
| </dependency> | ||
| | ||
| <dependency> | ||
| <groupId>org.springaicommunity</groupId> | ||
| <artifactId>spring-ai-bedrock-agentcore-starter</artifactId> | ||
| <version>1.0.0-SNAPSHOT</version> | ||
| </dependency> | ||
| | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-web</artifactId> | ||
| </dependency> | ||
| | ||
| <!-- JSON processing for MCP communication --> | ||
| <dependency> | ||
| <groupId>com.fasterxml.jackson.core</groupId> | ||
| <artifactId>jackson-databind</artifactId> | ||
| </dependency> | ||
| | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-test</artifactId> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| <dependencyManagement> | ||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.springframework.ai</groupId> | ||
| <artifactId>spring-ai-bom</artifactId> | ||
| <version>${spring-ai.version}</version> | ||
| <type>pom</type> | ||
| <scope>import</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </dependencyManagement> | ||
| | ||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-maven-plugin</artifactId> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use Spring's built-in containerization support instead (bootBuildImage)?