数字货币管理代理
与MCP(模型上下文协议)集成
作者 Ramanjaneya Reddy S\ 版本: 1.0.0\ 堆栈: Java 21·Spring Boot 3.3.7·Spring AI 1.0.0·Azure OpenAI·MCP
______________________________________________________________________
目录
______________________________________________________________________
1.工程概况
这个项目是 开发就绪的AI Agent 基于Spring Boot构建,可管理 数字货币数据,并通过Azure OpenAI提供人工智能驱动的投资智能。
随后,它被扩展为 MCP(模型上下文协议) --创建了一个开放标准 通过Anthropic-展示代理商作为标准化、可发现的API的能力 任何兼容MCP的AI客户端都可以连接和使用。
系统做什么
- 在数据库中存储和管理数字货币数据(价格、市值、时间戳)
- 为货币管理提供完整的CRUD REST API
- 通过Azure OpenAI GPT提供三种基于AI的分析功能:
- 个别货币投资分析 - 整个投资组合的市场趋势预测 - 投资组合优化建议
- 将所有AI功能公开为 MCP工具 --允许克劳德桌面,
其他AI代理和IDE插件以编程方式调用它们
为什么MCP很重要
在MCP之前,每个AI集成都需要双方的自定义代码。 MCP对合同进行标准化:
Without MCP: Agent A Agent B Agent C
With MCP: Agent A Agent B Agent C这与REST为web服务所做的转变相同——一种通用协议 每个参与者都在发言,而不是到处定制集成。
______________________________________________________________________
屏幕截图:
Run_Locally Postman Postman Postman Postman Postman
2.技术栈
| 层 | 技术 | 版本 | 目的 |
|---|---|---|---|
| 语言 | Java | 21 | 主要语言 |
| 框架 | Spring Boot | 3.3.7 | 应用框架 |
| AI框架 | Spring AI | 1.0.0 | MCP服务器,工具注册 |
| LLM提供商 | Azure OpenAI(GPT) | SDK 1.0.0-beta13 | 人工智能分析和预测 |
| HTTP客户端 | OkHttp(通过azure core HTTP OkHttp) | 由BOM管理 | 阻止HTTP,无Netty冲突 |
| 持久性 | Spring Data JPA | 由Boot管理 | ORM和存储库层 |
| 数据库 | H2(内存中) | 由Boot管理 | 开发数据库 |
| 验证 | 雅加达验证 | 由Boot管理 | 请求验证 |
| 构建 | Maven | 3.x | 构建和依赖关系管理 |
| 协议 | MCP over SSE | 1.0.0 | AI工具互操作性 |
密钥依赖设计决策——Netty上的OkHttp
Azure OpenAI SDK默认使用Netty进行HTTP传输。Spring AI MCP服务器 还使用Reactor Netty。当两者都在类路径上时,它们共享一个Netty事件 跨不兼容的线程上下文循环注册表(Spring MVC servlet线程vs 反应堆NIO线程),导致运行时失败。
解决方案: 排除 azure-core-http-netty 和使用 azure-core-http-okhttp 相反。OkHttp是纯阻塞的,没有事件循环——它在任何 线程,包括Spring MVC的servlet线程。
______________________________________________________________________
3.系统架构
高级体系结构
+------------------------------------------------------------------+
| CLIENT LAYER |
| |
| REST Clients MCP Clients |
| (Postman, browser, (Claude Desktop, other Spring AI agents, |
| frontend apps) IDE plugins like Cursor/VS Code) |
+--------+-----------------------+----------------------------------+
| |
| HTTP REST | MCP over SSE (HTTP)
| |
+--------v-----------------------v----------------------------------+
| SPRING BOOT APPLICATION |
| (port 8080) |
| |
| +------------------+ +--------------------------------+ |
| | REST Controllers | | MCP Server Layer | |
| | | | (Spring AI MCP) | |
| | /api/currencies | | GET /sse (connect) | |
| | /api/ai | | POST /mcp/message (tool call) | |
| | /api/mcp/info | | GET /api/mcp/info | |
| +--------+---------+ +---------------+----------------+ |
| | | |
| +--------------------------------+ |
| | |
| +-------------v--------------+ |
| | Service Layer | |
| | | |
| | DigitalCurrencyService | |
| | AzureAiService | |
| | CurrencyMcpTools | |
| +------+-----------+---------+ |
| | | |
| +--------v---+ +---v-----------+ |
| | Repository | | Azure OpenAI | |
| | (JPA) | | Client | |
| +--------+---+ | (OkHttp) | |
| | +---+-----------+ |
| +--------v---+ | |
| | H2 Database| | HTTPS |
| | (in-memory)| | |
| +------------+ +---v---------------------------+ |
| | Azure OpenAI Service (cloud) | |
| | GPT deployment | |
| +-------------------------------+ |
+------------------------------------------------------------------+包结构
com.azure.digitalcurrency
|
+-- AzureAiCurrencyApplication.java Spring Boot entry point
|
+-- config/
| +-- DataInitializer.java Seeds 5 sample currencies on startup
|
+-- model/
| +-- DigitalCurrency.java JPA entity (id, code, name, value, marketCap)
|
+-- repository/
| +-- DigitalCurrencyRepository.java JPA repository with custom queries
|
+-- service/
| +-- DigitalCurrencyService.java Business logic + orchestration
| +-- AzureAiService.java Azure OpenAI client wrapper
|
+-- controller/
| +-- DigitalCurrencyController.java CRUD REST endpoints (/api/currencies)
| +-- AiAnalysisController.java AI REST endpoints (/api/ai)
| +-- McpInfoController.java MCP info endpoint (/api/mcp/info)
|
+-- mcp/
+-- CurrencyMcpTools.java @Tool definitions — MCP tool implementations
+-- McpServerConfig.java Registers tools with Spring AI MCP server______________________________________________________________________
4.组件设计
4.1数字货币(实体)
核心域对象,映射到 digital_currency 桌子。
| 字段 | 类型 | 约束 | 描述 |
|---|---|---|---|
| id | Long | PK,自动生成 | 内部标识符 |
| currencyCode | String | 唯一,不为空 | 例如“BTC”、“ETH” |
| currencyName | String | 非空 | 例如“比特币” |
| currentValue | BigDecimal | 非空、正、精度(25.2) | 价格(美元) |
| marketCap | BigDecimal | 非空、正、精度(25.2) | 市值(美元) |
| createdAt | LocalDateTime | 持久化时自动 | 创建时间戳 |
| updatedAt | LocalDateTime | 更新时自动 | 上次更新时间戳 |
BigDecimal 故意用于货币价值-- double 和 float 不能精确地表示小数(IEEE 754二进制浮点), 这会导致财务计算中的舍入误差。
4.2数字货币存储库
扩展 JpaRepository 并补充道:
Optional findByCurrencyCode(String currencyCode);
List findByCurrencyNameContainingIgnoreCase(String name);
@Query("SELECT dc FROM DigitalCurrency dc ORDER BY dc.marketCap DESC")
List findAllOrderByMarketCapDesc();
@Query("SELECT dc FROM DigitalCurrency dc ORDER BY dc.currentValue DESC")
List findAllOrderByCurrentValueDesc();Spring Data JPA在运行时根据方法名生成SQL实现 和JPQL注释——不需要样板SQL。
4.3 AzureAiService
封装Azure OpenAI SDK,并提供三种AI操作。 每种方法都遵循相同的模式:
1. Build system message (defines AI persona/role)
2. Build user prompt (injects currency data from DB)
3. Call Azure OpenAI (getChatCompletions with deployment name)
4. Extract response text (choices[0].message.content)
5. Return or handle error with descriptive message关键设计选择——可配置部署名称: Azure OpenAI使用部署名称(由用户在Azure门户中设置), 不是型号名称。将其作为财产(azure.openai.deployment-name) 避免了硬编码,并使服务在Azure订阅之间可移植。
4.4数字货币服务
控制器/MCP工具和存储库/AI服务之间的编排层。 责任:
- 所有存储库访问都通过此服务进行(没有来自控制器的直接存储库调用)
- 构造传递给AI提示的数据上下文
- 将AI调用限制在前5种货币,以控制代币使用
4.5数据初始化器
实现 CommandLineRunner --种子5种货币(BTC、ETH、ADA、DOT、SOL) 如果表为空,则在首次启动时使用实际值。这意味着 应用程序在启动后立即可用,无需手动输入数据。
______________________________________________________________________
5.MCP集成设计
5.1什么是MCP?
模型上下文协议(MCP)是由Anthropic创建的开放标准 定义AI代理如何在 结构化、可发现的方式。
将其视为AI工具集成的REST标准:
- REST标准化了系统如何通过HTTP公开数据
- MCP规范了AI代理如何向LLM公开可调用工具
5.2本项目的MCP架构
此应用程序充当 MCP服务器。它暴露了任何工具 MCP客户端(Claude Desktop,另一个Spring AI代理,IDE插件)可以 发现并呼叫。
MCP Client MCP Server (this app)
| |
|-- GET /sse --------------------------->| (1) Establish SSE connection
|| (2) Discover available tools
|| (3) Call a tool
| |
| CurrencyMcpTools.analyzeInvestment("BTC")
| |
| DigitalCurrencyService.getInvestmentAnalysis("BTC")
| |
| AzureAiService.analyzeInvestmentOpportunity(...)
| |
| Azure OpenAI API call (HTTPS)
| |
| Your OpenAI resource > Keys and Endpoint
azure.openai.api-key=YOUR_API_KEY_HERE
# The DEPLOYMENT NAME from Azure OpenAI Studio > Deployments
# This is the name YOU gave your deployment — NOT the model name
# e.g. if you named your deployment "gpt-35-turbo", use that exactly
azure.openai.deployment-name=YOUR_DEPLOYMENT_NAME如何查找部署名称
- 首选https://oai.azure.com(Azure OpenAI工作室)
- 选择您的资源
- 点击 部署 在左侧菜单中
- 复制中的值 部署名称 列(不是模型列)
MCP服务器配置
spring.ai.mcp.server.enabled=true
spring.ai.mcp.server.name=digital-currency-agent
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.transport=SSE数据库配置(H2——开发)
spring.datasource.url=jdbc:h2:mem:digitalcurrency
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console访问H2控制台http://localhost:8080/h2-控制台\ JDBC网址: jdbc:h2:mem:digitalcurrency |用户名: sa |密码:(空)
______________________________________________________________________
11.项目运行
先决条件
- Java 21+
- Maven 3.6+
- 已部署GPT模型的Azure OpenAI资源
步骤
# 1. Clone or extract the project
cd cd digitalcurrency-mcp-agent
# 2. Set your Azure credentials in:
# src/main/resources/application.properties
# 3. Build
mvn clean install
# 4. Run
mvn spring-boot:run验证它是否正在运行
# Should return list of 5 seeded currencies
curl http://localhost:8080/api/currencies
# Should return AI market predictions
curl http://localhost:8080/api/ai/market-predictions
# Should return MCP server info and tool list
curl http://localhost:8080/api/mcp/info______________________________________________________________________
12.连接MCP客户端
克劳德桌面版
编辑(或创建)Claude Desktop配置文件:
- 雨衣:
~/Library/Application Support/Claude/claude_desktop_config.json - 窗户:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"digital-currency-agent": {
"transport": "sse",
"url": "http://localhost:8080/sse"
}
}
}重新启动克劳德桌面。工具图标(🔧) 将显示6个可用工具。
然后你可以自然地问克劳德:
- *“我的货币的市场预测是什么?”*
- *“从我的数据库对比比特币和以太坊”*
- *“我应该根据我的数据投资Solana吗?”*
Claude将调用相应的工具,从Spring Boot中获取响应 代理,并以对话的方式呈现。
另一个Spring AI代理
将此添加到其他代理的 application.yml:
spring:
ai:
mcp:
client:
enabled: true
toolcallback:
enabled: true
sse:
connections:
digital-currency:
url: http://localhost:8080Spring AI将自动发现并注册该代理LLM的所有6个工具。
______________________________________________________________________
13.工程决策和问题解决
在开发过程中解决了三个真正的工程挑战:
问题1-Java类型推理失败(编译错误)
错误:
incompatible types: Map>
cannot be converted to Map原因: Map.of() 使用混合值类型(String+BigDecimal)会导致Java 类型推断,以生成太窄而无法分配的交集类型 Map.
解决方案: 替换 Map.of() 随着 new HashMap<>() +明确的 put() 电话 无论不同类型的值混合在哪里。 HashMap 没有类型推理 在建设中——它总是 HashMap.
问题2-Netty事件循环冲突(运行时错误)
错误:
channel not registered to an event loop原因: Azure OpenAI SDK默认使用Netty进行HTTP传输。 MCP服务器依赖关系(spring-ai-starter-mcp-server-webmvc)也 将Reactor Netty拉到类路径中。两个Netty环境共享 全局事件循环注册表,但在不兼容的线程上下文中运行-- Spring MVC的servlet线程与Reactor的NIO线程。第一次通话 靠运气成功;来自错误线程上下文的后续调用失败。
解决方案: 两部分修复:
- 排除
azure-core-http-netty中的Azure AI依赖关系pom.xml - 添加
azure-core-http-okhttp并显式配置客户端:
.httpClient(new OkHttpAsyncHttpClientBuilder().build())OkHttp是纯阻塞的——没有事件循环,没有线程上下文冲突。
问题3-Azure OpenAI 500错误
错误:
{ "code": 500, "message": "Internal Server Error" }原因: 代码正在传递 "gpt-3.5-turbo" 作为模型标识符。 Azure OpenAI不使用OpenAI模型名称——它使用 部署名称 由用户在Azure OpenAI Studio中定义。传递未知名称的结果 在Azure的API的500中。
解决方案:
- 将部署名称设置为可配置属性:
azure.openai.deployment-name - 为每个HTTP状态码(401、404、500)添加了特定的错误消息
未来的配置错误可立即诊断
______________________________________________________________________
14.未来路线图
短期
- PostgreSQL --将H2替换为用于生产的持久数据库
- 实时价格 -集成CoinGecko或CoinMarketCap API以获取
实时价格和按计划自动更新数据库
- Spring Security -添加API密钥身份验证以保护终结点
中期
- 流媒体响应 -使用Azure OpenAI流API进行AI分析
逐令牌流式传输回客户端令牌,而不是等待完整响应
- 对话记忆 --使用Spring AI
ChatMemory保持上下文
在一个会话中跨越多个问题
- 其他MCP工具 —
update_price,add_currency,set_price_alert
长期
- 多代理架构 --将此代理作为工具提供程序连接到
高级编排器代理,可以将货币数据与新闻提要相结合, 监管警报和宏观经济指标
- MCP资源风险 --将货币数据库作为MCP资源公开
(不仅仅是工具),允许客户订阅价格变动通知
______________________________________________________________________
*基于Spring Boot 3.3.7构建·Spring AI 1.0.0·Azure OpenAI·MCP*
