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

# 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 @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

# 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

Description
No description provided
Readme 67 MiB
Languages
Java 83.4%
TypeScript 13.4%
Python 0.9%
PowerShell 0.6%
Shell 0.6%
Other 1.1%