147 lines
4.8 KiB
Markdown
147 lines
4.8 KiB
Markdown
# Loyalty Agent Service
|
|
|
|
A production-ready AI-powered assistant for managing a Loyalty platform, built on the **Model Context Protocol (MCP)**.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Frontend (React/Vite :9333)
|
|
↓ WebSocket (STOMP)
|
|
loyalty-agent (:9332) ← Orchestrator + BFF
|
|
↓ MCP SSE Transport (/sse, /message)
|
|
loyalty-mcp-server (:9331) ← MCP Tool Server
|
|
↓ REST + OAuth2 (Keycloak)
|
|
Loyalty Core API (:8081) ← Backend Services
|
|
```
|
|
|
|
### Modules
|
|
|
|
| Module | Port | Role |
|
|
|--------|------|------|
|
|
| `loyalty-mcp-server` | 9331 | MCP Server — exposes 25 tools via SSE transport |
|
|
| `loyalty-agent` | 9332 | AI Agent — orchestrates LLM + MCP tools |
|
|
| Frontend (root) | 9333 | React/Vite chat UI |
|
|
|
|
## Technology Stack
|
|
|
|
- **Java 25**, Spring Boot 4.0.0, Spring AI 2.x
|
|
- **MCP Transport**: SSE (WebMVC) via `spring-ai-starter-mcp-server-webmvc`
|
|
- **LLM**: Ollama (qwen3.5:4b, configurable)
|
|
- **Auth**: Keycloak OAuth2 Client Credentials
|
|
- **Persistence**: PostgreSQL (agent conversation history)
|
|
- **Frontend**: React + Vite + WebSocket (STOMP)
|
|
|
|
## MCP Capabilities
|
|
|
|
### Tools (25 registered)
|
|
|
|
| Category | Tools |
|
|
|----------|-------|
|
|
| Campaign | `searchCampaigns`, `countCampaigns`, `getCampaignById`, `getCampaignsByIds`, `generateCampaignId`, `checkCampaignId`, `createCampaign` |
|
|
| Campaign Rule | `searchRules`, `countRules`, `getRuleById`, `getRulesByIds`, `generateRuleId`, `checkRuleId`, `createRule`, `findMatchingRules` |
|
|
| Pool Definition | `getPoolDefinitionById`, `getPoolDefinitionsByIds`, `searchPoolDefinitions` |
|
|
| Counter | `getCounterDefinitionById`, `getCounterDefinitionsByIds` |
|
|
| Deduction Sequence | `getDeductionSequenceById`, `getDefaultDeductionSequence` |
|
|
| Transaction Code | `getTransactionCode`, `getTransactionCodes`, `checkTransactionCodeExists` |
|
|
|
|
### Resources & Prompts
|
|
- Resources, resource templates, prompts, and completions capabilities are enabled via Spring AI autoconfiguration
|
|
- Currently no custom resources or prompts defined (the autoconfiguration registers empty capability declarations)
|
|
|
|
### Transport
|
|
- **SSE**: `/sse` endpoint for server-sent events
|
|
- **Message**: `/message` endpoint for client-to-server messages
|
|
- **Keep-alive**: 30-second interval configured
|
|
|
|
## Startup Instructions
|
|
|
|
### Prerequisites
|
|
- Java 25+
|
|
- Node.js & pnpm
|
|
- PostgreSQL (for agent persistence)
|
|
- `.env` file created (see `.env` for template)
|
|
|
|
### Start Backend Modules
|
|
```bash
|
|
# Start both modules with one script:
|
|
./start-all.sh
|
|
|
|
# Or start individually:
|
|
./mvnw spring-boot:run -pl loyalty-mcp-server
|
|
./mvnw spring-boot:run -pl loyalty-agent
|
|
```
|
|
|
|
### Start Frontend
|
|
```bash
|
|
pnpm install
|
|
pnpm dev
|
|
```
|
|
|
|
### Configuration
|
|
|
|
Key environment variables (see `.env`):
|
|
|
|
| Variable | Description |
|
|
|----------|-------------|
|
|
| `LOYALTY_CORE_BASE_URL` | Base URL for Loyalty Core API |
|
|
| `KEYCLOAK_TOKEN_URI` | Keycloak token endpoint |
|
|
| `KEYCLOAK_CLIENT_ID` | OAuth2 client ID |
|
|
| `KEYCLOAK_CLIENT_SECRET` | OAuth2 client secret |
|
|
| `SPRING_DATASOURCE_URL` | PostgreSQL connection for agent |
|
|
| `OLLAMA_BASE_URL` | Ollama LLM endpoint |
|
|
|
|
## Error Handling
|
|
|
|
- **AOP Aspect** (`GlobalToolExceptionHandlerAspect`): Wraps all `@McpTool` methods, catches exceptions and returns safe `Result.failure()` responses
|
|
- **REST Exception Handler** (`GlobalMcpExceptionHandler`): Catches transport-level exceptions with safe error response
|
|
- **Agent-side** (`ToolInterceptor`): Sanitizes error responses, auto-reconnects on dropped SSE connections, truncates large results
|
|
|
|
## Security
|
|
|
|
- OAuth2 Client Credentials flow for backend API authentication
|
|
- No internal stack traces or credentials exposed to MCP client
|
|
- Input validation on all tool parameters
|
|
- Response body logging limited to debug level with truncation
|
|
|
|
## Running Tests
|
|
|
|
```bash
|
|
# All tests
|
|
./mvnw test
|
|
|
|
# MCP server tests only
|
|
./mvnw test -pl loyalty-mcp-server
|
|
|
|
# Agent tests only
|
|
./mvnw test -pl loyalty-agent
|
|
```
|
|
|
|
## Health Checks
|
|
|
|
Both services expose Spring Boot Actuator health endpoints:
|
|
|
|
```
|
|
GET /actuator/health — Overall health
|
|
GET /actuator/health/liveness — Kubernetes liveness probe
|
|
GET /actuator/health/readiness — Kubernetes readiness probe
|
|
```
|
|
|
|
## Additional Tools (Domain Services)
|
|
|
|
| Category | Tools |
|
|
|----------|-------|
|
|
| App Param | `searchAppParam`, `getAppParamById` |
|
|
| Dynamic Attribute | `searchDynamicAttribute`, `getDynamicAttributeById` |
|
|
| Journey | `searchJourney`, `getJourneyById` |
|
|
| User | `searchUser`, `getUserById` |
|
|
| Customer | `searchCustomers`, `getCustomerById` |
|
|
| Catalogue | `searchCatalogues`, `getCatalogueById` |
|
|
| Transaction | `searchTransactions`, `getTransactionById` |
|
|
|
|
## Further Documentation
|
|
|
|
- [ARCHITECTURE.md](ARCHITECTURE.md) — System architecture, data flow, security model
|
|
- [DEPLOYMENT.md](DEPLOYMENT.md) — Production deployment guide
|
|
- [.env.example](.env.example) — Environment variable template
|
|
|