--- trigger: always_on --- # Application Context: `loyalty-mcp-server` Application Name: **Loyalty MCP Server** Module Path: `loyalty-mcp-server/` Runtime Port: `9331` Technology Stack: Java 25, Spring Boot 4.x, Spring AI 2.x MCP Server (`spring-ai-mcp-server-spring-boot-starter`), OAuth2 RestClient, OpenAPI Specs --- ## 1. Primary Roles & Responsibilities `loyalty-mcp-server` operates as a standalone **MCP Tool Server**: - **Expose Tools to Agent**: Encapsulates loyalty business capabilities into standardized Model Context Protocol (MCP) tools. - **MCP SSE Transport**: Exposes an SSE endpoint (`/sse`) and a Message endpoint (`/message`) for `loyalty-agent` to connect and execute tools remotely. - **Loyalty Core API Integration**: Directly calls the Loyalty Core Backend API to query and manipulate domain entities (Campaigns, Rules, Point Pools, Members, Attributes...). - **Response Standardization & Exception Safety**: Wraps tool outputs in standard `Result` and `OperationResult` structures, supplying a `presentation.content` Markdown snippet for direct user display. --- ## 2. Business Tool Registry Tools are registered using the `@McpTool` annotation in the `dev.sonpx.loyalty.mcp.tool` package. ### A. Campaign Management (`CampaignTools.java`) - **`searchCampaigns(request)`**: Searches campaigns by criteria (name, code, owner, type). Returns a list of `CampaignSummaryDto`. - **`countCampaigns(request)`**: Returns the total count of campaigns matching criteria. - **`getCampaignById(id)` / `getCampaignsByIds(ids)`**: Fetches details for one or multiple campaigns by ID. - **`generateCampaignId()` / `checkCampaignId(id)`**: Generates a new campaign ID or verifies ID validity. - **`createCampaign(Campaign dto)`**: Creates a new loyalty campaign. ### B. Campaign Rule Management (`CampaignRuleTools.java`) - **`searchRules(request)`**: Searches campaign rules by criteria (name, campaign, type, dates). Returns `CampaignRuleSummaryDto`. - **`countRules(request)`**: Returns the total count of rules matching criteria. - **`getRuleById(id)` / `getRulesByIds(ids)`**: Fetches details for one or multiple rules by ID. - **`generateRuleId()` / `checkRuleId(id)`**: Generates a new rule ID or checks ID validity. - **`createRule(CampaignRule dto)`**: Creates a new campaign rule. - **`findMatchingRules(ruleType, transactionCode, transactionDate, postDate, languageCode)`**: Finds rules matching a specific transaction. ### C. Pool Definition (`PoolDefinitionTools.java`) - **`getPoolDefinitionById(poolId)`**: Fetches details for a Point Pool. - **`getPoolDefinitionsByIds(ids)`**: Fetches multiple pools by IDs. - **`searchPoolDefinitions(request)`**: Searches pools by criteria. ### D. Counter Definition (`CounterDefinitionTools.java`) - **`getCounterDefinitionById(counterId)`**: Fetches details for a Counter. - **`getCounterDefinitionsByIds(ids)`**: Fetches multiple counters by IDs. ### E. Deduction Sequence (`DeductionSequenceTools.java`) - **`getDeductionSequenceById(deductionSeqId)`**: Fetches a deduction sequence config. - **`getDefaultDeductionSequence()`**: Fetches the system default deduction sequence. ### F. Transaction Code (`TransactionCodeTools.java`) - **`getTransactionCode(transactionCode)`**: Fetches details for a transaction code. - **`getTransactionCodes(transactionCodes)`**: Fetches multiple transaction codes. - **`checkTransactionCodeExists(transactionCode)`**: Checks if a transaction code exists. --- ## 3. Loyalty Core API Integration & OpenAPI Specs - **OAuth2 Client Credentials Authentication**: - Automatically fetches Bearer tokens from Keycloak (`KEYCLOAK_TOKEN_URI`, `KEYCLOAK_CLIENT_SECRET`). - Attaches authorization headers to requests sent to `LOYALTY_CORE_BASE_URL` (`http://192.168.99.88:8081`). - **OpenAPI Specs Registry**: - Located at `src/main/resources/specs/`: - `master.json`, `marketing.json`, `reward.json`, `customer.json`, `attribute.json`, `catalogue.json`, `transaction.json`, `identity.json`. - Serves as the authoritative schema reference for DTOs and API payloads. --- ## 4. Response Wrapping & Exception Handling ### Standardized Response Wrapper All tools return `Result`: - `data`: T (Payload data, null on validation errors) - `_agent_instruction`: String (Instructions for the LLM on how to present the data, or `VALIDATION_ERROR: ...` for validation failures) The `_agent_instruction` field is transformed by the agent's `ToolResultPresentationProcessor` into `agent_instruction` before being sent to the LLM. ### Exception Handling (`aspect/` & `exception/`) - `GlobalToolExceptionHandlerAspect`: AOP aspect that intercepts exceptions across all `@McpTool` methods. - `GlobalMcpExceptionHandler`: Catches Core API failures (HTTP 4xx, 5xx, timeouts) and formats them into clean `Result.failure(...)` objects for the LLM without crashing the invocation stream. --- ## 5. Key Development Guidelines for Agents 1. **Tool Prompting Quality (`description`)**: `@McpTool` descriptions act as direct system prompt instructions for the LLM when choosing tools. Keep descriptions precise, clear, and explicit (e.g., instructing the LLM not to pass generic terms like "campaign" into search queries). 2. **Strict Adherence to `Result`**: Never return raw null values or throw unhandled `RuntimeException`s from tool methods. 3. **Clear Tool Boundaries**: `CampaignTools` handles top-level campaign metadata. `CampaignRuleTools` handles reward formulas, conditions, and rules. 4. **MCP Ports**: Maintain server execution on port `9331` at endpoints `/sse` and `/message`.