模型上下文协议演示

一个展示Spring AI中模型上下文协议(MCP)的演示项目,包括MCP服务器、客户端和模型无关的主机实现。

  • by sandipanchakraborty2016
  • Java
  • 本地部署
  • 更新于
在 GitHub 查看 sandipanchakraborty2016/spring-ai-mcp-demo

使用说明

Spring AI MCP演示

全面展示 模型上下文协议(MCP) 使用Spring AI,具有功能齐全的MCP服务器、客户端和 与模型无关的主机实现 有多个工具示例。

📘 架构指南:参见 建筑.md 有关MCP协议使用与REST包装器的详细说明。

🎯 项目概述

该项目展示了Spring AI的MCP实现,包括:

  • MCP服务器 (端口8080):通过服务器发送事件(SSE)和 @McpTool 注释
  • MCP客户端 (端口8081):用于直接工具访问的REST API包装器(方便端点,不使用MCP协议)
  • MCP主机OpenAI (端口8082):✅ 真正的MCP演示 -通过MCP协议使用OpenAI GPT和工具进行AI聊天
  • MCP主持人克劳德 (端口8083):✅ 真正的MCP演示 -使用Anthropic Claude通过MCP协议与工具进行人工智能聊天
  • 弹簧靴3.4.12 和 春季AI 1.1.0-M2
  • 码头工人 支持容器化部署
  • 模型不可知设计:相同的MCP工具适用于不同的AI提供商

🔍 MCP协议与REST API

  • MCP协议 (SSE+JSON-RPC):用于 mcp-host ChatModel调用工具的地方✅
  • REST包装器API:用于 mcp-client 用于直接工具测试(非MCP协议)⚠️

🌟 关键特性:模型不可知MCP

此演示证明了MCP的 模型不可知 性质:

  • 一台MCP服务器 提供工具(计算器、时间、文件、存储)
  • 多种AI模型 可以使用相同的工具:
    • OpenAI GPT模型(端口8082上的mcp主机)
    • 拟人克劳德模型(8083端口上的mcp主机克劳德)
  • 无服务器更改 需要支持不同的模型
  • 相同的工具,不同的智能 -比较不同模型如何使用相同的工具

🏗️ 建筑

┌──────────────────┐        ┌──────────────────┐        ┌─────────────────┐
│  MCP Host        │        │  MCP Host        │        │   MCP Client    │
│  (OpenAI)        │        │  (Claude)        │        │   (Port 8081)   │
│  Port 8082       │        │  Port 8083       │        │                 │
│                  │        │                  │        │   REST API      │
│  GPT-4 + Tools   │        │ Claude + Tools   │        │   Endpoints     │
└────────┬─────────┘        └────────┬─────────┘        └────────┬────────┘
         │                           │                           │
         │                           │                           │
         │  Uses MCP Tools           │  Uses MCP Tools           │ Calls MCP Tools
         │                           │                           │
         └───────────────────────────┴───────────────────────────┘
                                     │
                                     │ SSE/HTTP
                                     ▼
                            ┌─────────────────┐
                            │   MCP Server    │
                            │   (Port 8080)   │
                            └─────────────────┘
                                     │
                                     │ Exposes Tools
                                     ▼
                            ┌──────────────────┐
                            │ • Time Service   │
                            │ • Calculator     │
                            │ • File Ops       │
                            │ • Data Storage   │
                            └──────────────────┘

模型不可知设计:OpenAI和Claude主机都使用 相同 MCP服务器和工具!

🚀 可用工具

时间服务

  • getCurrentTime() -返回当前时间戳

计算服务

  • add(a, b) -补充
  • subtract(a, b) -减法
  • multiply(a, b) -乘法
  • divide(a, b) -分部
  • power(base, exponent) -指数化
  • sqrt(number) -平方根

文件服务

  • readFile(filename) -读取文件内容
  • writeFile(filename, content) -创建或覆盖文件
  • appendToFile(filename, content) -附加到现有文件
  • listFiles() -列出工作区中的所有文件
  • deleteFile(filename) -删除文件
  • getFileInfo(filename) -获取文件大小和元数据
  • getWorkspacePath() -获取工作区目录路径

数据存储服务

  • store(key, value) -存储键值对
  • retrieve(key) -按键检索值
  • delete(key) -删除条目
  • listKeys() -列出所有密钥
  • clear() -清除所有数据
  • count() -计数条目

📋 先决条件

  • Java 21 JDK (不仅仅是JRE,还包括编译器)
  • Maven 3.6+
  • 码头工人 和 Docker Compose (用于集装箱化部署)

安装Java 21 JDK

# Ubuntu/Debian
sudo apt-get update && sudo apt-get install openjdk-21-jdk

# Verify installation
javac -version  # Should show: javac 21.x.x

🏃 快速开始

Docker Compose(推荐)

启动所有服务 (MCP服务器+客户端+两个AI主机):

docker-compose up --build

这将开始:

  • MCP服务器 在端口8080上
  • MCP客户端 在端口8081上
  • MCP主机(OpenAI) 在端口8082上
  • MCP主持人(克劳德) 在端口8083上

环境变量

开始之前,请设置API密钥:

# For OpenAI host
export SPRING_AI_OPENAI_API_KEY="your-openai-api-key"

# For Claude host
export ANTHROPIC_API_KEY="your-anthropic-api-key"

或者创建一个 .env 文件:

SPRING_AI_OPENAI_API_KEY=your-openai-api-key
ANTHROPIC_API_KEY=your-anthropic-api-key

地方发展(个人服务)

  1. 构建所有项目

    mvn clean package -f mcp-server/pom.xml
    mvn clean package -f mcp-client/pom.xml
    mvn clean package -f mcp-host/pom.xml
    mvn clean package -f mcp-host-claude/pom.xml
    
  2. 单独启动服务

    # Terminal 1: MCP Server
    cd mcp-server && mvn spring-boot:run
    
    # Terminal 2: MCP Client
    cd mcp-client && mvn spring-boot:run
    
    # Terminal 3: MCP Host (OpenAI)
    cd mcp-host && mvn spring-boot:run
    
    # Terminal 4: MCP Host (Claude)
    cd mcp-host-claude && mvn spring-boot:run
    

🔌 API示例

OpenAI与Claude的比较(模型不可知论演示)

两个主机都提供相同的端点-使用相同的查询进行测试以进行比较!

MCP主机-OpenAI(端口8082)

# Get host information
curl http://localhost:8082/

# Check available MCP tools
curl http://localhost:8082/api/mcp-info

# Simple calculation
curl "http://localhost:8082/api/demo?query=What+is+25+times+4"

MCP主机-克劳德(端口8083)

# Get host information
curl http://localhost:8083/

# Check available MCP tools (same tools, different model!)
curl http://localhost:8083/api/mcp-info

# Same calculation with Claude
curl "http://localhost:8083/api/demo?query=What+is+25+times+4"

两者都试试,比较一下:向OpenAI和Claude主机提出同样的问题——他们使用相同的MCP工具,但可能会有不同的反应!

MCP客户端-直接工具访问

列出可用工具

curl http://localhost:8081/api/tools

时间服务

curl http://localhost:8081/api/time

计算器操作

# Addition
curl "http://localhost:8081/api/calculator/add?a=10&b=5"

# Division
curl "http://localhost:8081/api/calculator/divide?a=20&b=4"

# Power
curl "http://localhost:8081/api/calculator/power?base=2&exponent=8"

文件操作

# List files
curl "http://localhost:8081/api/files/list"

# Write a file
curl -X POST "http://localhost:8081/api/files/write?filename=test.txt&content=Hello%20World"

# Read a file
curl "http://localhost:8081/api/files/read?filename=test.txt"

# Append to file
curl -X POST "http://localhost:8081/api/files/append?filename=test.txt&content=%0ANew%20line"

# Get file info
curl "http://localhost:8081/api/files/info?filename=test.txt"

# Delete file
curl -X DELETE "http://localhost:8081/api/files/delete?filename=test.txt"

# Get workspace path
curl "http://localhost:8081/api/files/workspace"

数据存储

# Store data
curl -X POST "http://localhost:8081/api/storage/store?key=username&value=john_doe"

# Retrieve data
curl "http://localhost:8081/api/storage/retrieve?key=username"

# List all keys
curl "http://localhost:8081/api/storage/list"

# Delete entry
curl -X DELETE "http://localhost:8081/api/storage/delete?key=username"

🌐 部署

看 部署.md 有关以下内容的详细部署说明:

  • Render.com(免费版)
  • Railway.app
  • Fly.io
  • 其他云平台

📁 项目结构

spring-ai-mcp-demo/
├── mcp-server/                 # MCP Server (provides tools)
│   ├── src/main/java/
│   │   └── com/example/mcpserver/
│   │       ├── McpServerApplication.java
│   │       ├── TimeService.java         # @McpTool
│   │       ├── CalculatorService.java   # @McpTool
│   │       ├── FileService.java         # @McpTool
│   │       ├── DataStorageService.java  # @McpTool
│   │       └── HealthController.java
│   ├── Dockerfile
│   └── pom.xml
│
├── mcp-client/                 # MCP Client (calls tools directly)
│   ├── src/main/java/
│   │   └── com/example/mcpclient/
│   │       ├── McpClientApplication.java
│   │       ├── ClientController.java
│   │       └── HealthController.java
│   ├── Dockerfile
│   └── pom.xml
│
├── mcp-host/                   # MCP Host with OpenAI
│   ├── src/main/java/
│   │   └── com/example/mcphost/
│   │       ├── McpHostApplication.java
│   │       ├── ChatController.java      # AI chat endpoints
│   │       └── HealthController.java
│   ├── Dockerfile
│   └── pom.xml
│
├── mcp-host-claude/            # MCP Host with Claude (Anthropic)
│   ├── src/main/java/
│   │   └── com/example/mcphostclaude/
│   │       ├── McpHostClaudeApplication.java
│   │       ├── ClaudeChatController.java
│   │       ├── ClaudeConfig.java
│   │       └── HealthController.java
│   ├── Dockerfile
│   └── pom.xml
│
├── docker-compose.yml          # Orchestrates all 4 services
├── render.yaml                 # Deployment configuration
└── README.md

🔧 配置

MCP服务器配置

mcp-server/src/main/resources/application.properties:

server.port=8080
spring.ai.mcp.server.transport=sse
spring.ai.mcp.server.sse.message-endpoint=/mcp/message

MCP客户端配置

mcp-client/src/main/resources/application.properties:

server.port=8081
spring.ai.mcp.client.transport=sse
spring.ai.mcp.client.sse.base-url=http://localhost:8080
spring.ai.mcp.client.sse.message-endpoint=/mcp/message

MCP主机(OpenAI)配置

mcp-host/src/main/resources/application.properties:

server.port=8082
spring.ai.openai.api-key=${SPRING_AI_OPENAI_API_KEY:demo-key}
spring.ai.openai.chat.options.model=gpt-4
spring.ai.mcp.client.sse.base-url=${SPRING_AI_MCP_CLIENT_SSE_BASE_URL:http://localhost:8080}

MCP主机(克劳德)配置

mcp-host-claude/src/main/resources/application.properties:

server.port=8083
spring.ai.anthropic.api-key=${ANTHROPIC_API_KEY:demo-key}
spring.ai.anthropic.chat.options.model=claude-3-5-sonnet-20241022
spring.ai.mcp.client.sse.base-url=${SPRING_AI_MCP_CLIENT_SSE_BASE_URL:http://localhost:8080}

🧪 测试

健康检查

# MCP Server health
curl http://localhost:8080/health

# MCP Client health
curl http://localhost:8081/health

# MCP Host (OpenAI) health
curl http://localhost:8082/health

# MCP Host (Claude) health
curl http://localhost:8083/health

测试模型不可知MCP

对两个AI模型的查询相同:

# Ask OpenAI
curl "http://localhost:8082/api/demo?query=What+time+is+it+and+calculate+50+divided+by+5"

# Ask Claude (same tools, different reasoning!)
curl "http://localhost:8083/api/demo?query=What+time+is+it+and+calculate+50+divided+by+5"

工具发现

# List all available tools from MCP Client
curl http://localhost:8081/api/tools

# Check MCP info from OpenAI host
curl http://localhost:8082/api/mcp-info

# Check MCP info from Claude host
curl http://localhost:8083/api/mcp-info

📚 了解更多

🤝 贡献

欢迎投稿!请随时提交拉取请求。

📄 许可证

该项目根据MIT许可证获得许可。

🙋 支持

有关问题和疑问,请在存储库中打开问题。