8ecd27dd0e704caa36fddcc0741662d0f3e0942c
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:
/sseendpoint for server-sent events - Message:
/messageendpoint for client-to-server messages - Keep-alive: 30-second interval configured
Startup Instructions
Prerequisites
- Java 25+
- Node.js & pnpm
- PostgreSQL (for agent persistence)
.envfile created (see.envfor template)
Start Backend Modules
# 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
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@McpToolmethods, catches exceptions and returns safeResult.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
# 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 — System architecture, data flow, security model
- DEPLOYMENT.md — Production deployment guide
- .env.example — Environment variable template
Description
Languages
Java
83.4%
TypeScript
13.4%
Python
0.9%
PowerShell
0.6%
Shell
0.6%
Other
1.1%