npm package: @open-loyalty/mcp-server
Description: MCP server for Open Loyalty API - enables AI agents to manage loyalty programs, members, points, rewards, and transactions
Author: Marcin Dyguda
Latest version: 1.14.1

# Open Loyalty MCP Server

MCP (Model Context Protocol) server for interacting with Open Loyalty API. This server enables AI agents like Claude and ChatGPT to manage loyalty programs, members, points, rewards, and transactions.

## Prerequisites

- Node.js 18 or later
- An Open Loyalty account with API access

## Installation

### Via npm (Recommended)

```bash
npm install -g @open-loyalty/mcp-server
```

Or use directly with npx (no installation required):

```bash
npx @open-loyalty/mcp-server
```

### From Source

```bash
git clone https://github.com/OpenLoyalty/openloyalty-mcp.git
cd openloyalty-mcp/openloyalty-mcp
npm install
npm run build
```

## Configuration

The server requires the following environment variables:

| Variable | Description |
|----------|-------------|
| `OPENLOYALTY_API_URL` | Your Open Loyalty API URL (e.g., `https://api.openloyalty.io`) |
| `OPENLOYALTY_API_TOKEN` | Your API authentication token |
| `OPENLOYALTY_DEFAULT_STORE_CODE` | Default store code (e.g., `default`) |

For local development, create a `.env` file based on `.env.example`:

```bash
cp .env.example .env
```

## Transport Modes

The server supports two transport modes for different use cases:

| Mode | Binary | Use Case |
|------|--------|----------|
| **stdio** | `openloyalty-mcp` | Local usage with Claude Desktop, Claude Code, Cursor |
| **HTTP** | `openloyalty-mcp-http` | Remote hosting, ChatGPT Actions, web integrations |

Both modes provide identical functionality - only the transport layer differs.

---

## Stdio Mode (Local)

Use stdio mode when running the server locally with MCP clients like Claude Desktop.

### Claude Desktop Configuration

Add this to your Claude Desktop configuration file:
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

#### Using npx (Recommended)

```json
{
  "mcpServers": {
    "openloyalty": {
      "command": "npx",
      "args": ["-y", "@open-loyalty/mcp-server"],
      "env": {
        "OPENLOYALTY_API_URL": "https://your-instance.openloyalty.io",
        "OPENLOYALTY_API_TOKEN": "your-api-token",
        "OPENLOYALTY_DEFAULT_STORE_CODE": "default"
      }
    }
  }
}
```

#### Using Global Installation

```json
{
  "mcpServers": {
    "openloyalty": {
      "command": "openloyalty-mcp",
      "env": {
        "OPENLOYALTY_API_URL": "https://your-instance.openloyalty.io",
        "OPENLOYALTY_API_TOKEN": "your-api-token",
        "OPENLOYALTY_DEFAULT_STORE_CODE": "default"
      }
    }
  }
}
```

#### Using Local Build

```json
{
  "mcpServers": {
    "openloyalty": {
      "command": "node",
      "args": ["/path/to/openloyalty-mcp/dist/index.js"],
      "env": {
        "OPENLOYALTY_API_URL": "https://your-instance.openloyalty.io",
        "OPENLOYALTY_API_TOKEN": "your-api-token",
        "OPENLOYALTY_DEFAULT_STORE_CODE": "default"
      }
    }
  }
}
```

---

## HTTP Mode (Remote Hosting)

Use HTTP mode when hosting the server remotely for web-based MCP clients or ChatGPT Actions.

### Running HTTP Server

```bash
# Using the binary
openloyalty-mcp-http

# Using npm scripts
npm run start:http

# Development mode
npm run dev:http
```

### HTTP Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `OPENLOYALTY_API_URL` | Yes* | Open Loyalty API URL |
| `OPENLOYALTY_API_TOKEN` | Yes* | API authentication token |
| `OPENLOYALTY_DEFAULT_STORE_CODE` | Yes* | Default store code |
| `PORT` or `MCP_HTTP_PORT` | No | Server port (default: 3000) |
| `OAUTH_ENABLED` | No | Enable multi-tenant OAuth mode |
| `BASE_URL` | OAuth | Public URL for OAuth callbacks |
| `REDIS_URL` | OAuth | Redis URL for token storage |

*Required when `OAUTH_ENABLED` is not set or `false`

### HTTP Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/` | GET | Server info |
| `/health` | GET | Health check |
| `/mcp` | POST | MCP message endpoint |
| `/mcp` | GET | SSE stream (with session) |
| `/mcp` | DELETE | Close session |

### Single-Tenant Mode

For dedicated deployments with fixed credentials:

```bash
export OPENLOYALTY_API_URL="https://api.openloyalty.io"
export OPENLOYALTY_API_TOKEN="your-token"
export OPENLOYALTY_DEFAULT_STORE_CODE="default"
openloyalty-mcp-http
```

### Multi-Tenant OAuth Mode

For shared deployments where each user provides their own credentials:

```bash
export OAUTH_ENABLED=true
export BASE_URL="https://your-server.com"
export REDIS_URL="redis://localhost:6379"
openloyalty-mcp-http
```

With OAuth enabled, additional endpoints are available:

| Endpoint | Description |
|----------|-------------|
| `/authorize` | OAuth authorization form |
| `/token` | Token exchange |
| `/register` | Dynamic client registration |
| `/.well-known/oauth-authorization-server` | OAuth metadata |

### ChatGPT Actions Integration

To use with ChatGPT:

1. Host the HTTP server with OAuth enabled
2. In GPT Editor → Configure → Actions:
   - Authentication: OAuth
   - Authorization URL: `https://your-server.com/authorize`
   - Token URL: `https://your-server.com/token`
   - Scope: `mcp`
3. Add your MCP endpoint: `https://your-server.com/mcp`

Users will be prompted to enter their Open Loyalty credentials during the OAuth flow.

---

## Development

```bash
# Run stdio server in development mode
npm run dev

# Run HTTP server in development mode
npm run dev:http

# Build for production
npm run build

# Run tests
npm test

# Type checking
npm run typecheck
```

---

## Available Tools (112 total)

### Wallet Types (2 tools)
- `ol_wallet_type_list` - List all wallet types (point currencies)
- `ol_wallet_type_get` - Get details for a specific wallet type

### Tier Sets (6 tools)
- `ol_tierset_list` - List all tier sets
- `ol_tierset_create` - Create a new tier set
- `ol_tierset_get` - Get tier set details with condition IDs
- `ol_tierset_update` - Update tier set metadata
- `ol_tierset_update_tiers` - Define tier thresholds
- `ol_tierset_get_tiers` - Get all tiers in a tier set

### Members (10 tools)
- `ol_member_create` - Register a new loyalty program member
- `ol_member_get` - Get member details including profile, points balance, and tier status
- `ol_member_list` - Search and list members with optional filters
- `ol_member_update` - Update member profile fields
- `ol_member_activate` - Activate a deactivated member
- `ol_member_deactivate` - Deactivate an active member
- `ol_member_delete` - Permanently remove member (GDPR compliance)
- `ol_member_get_tier_progress` - Get tier progression status
- `ol_member_assign_tier` - Manually assign tier to member
- `ol_member_remove_manual_tier` - Remove manual tier assignment

### Points (6 tools)
- `ol_points_add` - Add points to member wallet (with optional expiration/lock)
- `ol_points_spend` - Deduct points from member wallet
- `ol_points_transfer` - Transfer points between members (P2P)
- `ol_points_get_balance` - Get member points balance breakdown
- `ol_points_get_history` - Get points transaction history
- `ol_points_get_histogram` - Get points histogram for visualization

### Rewards (9 tools)
- `ol_reward_list` - List available rewards
- `ol_reward_create` - Create a new reward
- `ol_reward_get` - Get reward details
- `ol_reward_update` - Update reward configuration
- `ol_reward_activate` - Activate a reward
- `ol_reward_deactivate` - Deactivate a reward
- `ol_reward_buy` - Purchase reward for member (deducts points)
- `ol_reward_redeem` - Mark coupon as used
- `ol_reward_category_list` - List reward categories

### Transactions (4 tools)
- `ol_transaction_create` - Record a purchase transaction
- `ol_transaction_get` - Get transaction details
- `ol_transaction_list` - List transactions with filters
- `ol_transaction_assign_member` - Assign unmatched transaction to member

### Campaigns (12 tools)
- `ol_campaign_list` - List all campaigns with optional filters
- `ol_campaign_create` - Create campaign to automate engagement
- `ol_campaign_get` - Get full campaign configuration
- `ol_campaign_update` - Update campaign (full replacement)
- `ol_campaign_patch` - Patch campaign (active/displayOrder only)
- `ol_campaign_delete` - Permanently delete a campaign
- `ol_campaign_simulate` - Preview campaign effects without executing
- `ol_campaign_generate_codes` - Generate redemption codes
- `ol_campaign_list_codes` - List redemption codes
- `ol_campaign_get_available` - Get campaigns available for member
- `ol_campaign_get_visible` - Get campaigns visible to member
- `ol_campaign_get_leaderboard` - Get campaign leaderboard

### Segments (9 tools)
- `ol_segment_list` - List customer segments
- `ol_segment_create` - Create segment to group members
- `ol_segment_get` - Get segment details with criteria
- `ol_segment_update` - Update segment configuration
- `ol_segment_delete` - Permanently delete a segment
- `ol_segment_get_members` - Get members matching segment
- `ol_segment_activate` - Activate a segment
- `ol_segment_deactivate` - Deactivate a segment
- `ol_segment_get_resources` - Get resources associated with segment

### Achievements (7 tools)
- `ol_achievement_list` - List achievements
- `ol_achievement_create` - Create achievement for gamification
- `ol_achievement_get` - Get achievement details
- `ol_achievement_update` - Update achievement (full replacement)
- `ol_achievement_patch` - Patch achievement (active/displayOrder)
- `ol_achievement_get_member_progress` - Get member's progress on achievement
- `ol_achievement_list_member_achievements` - List member's achievements

### Badges (4 tools)
- `ol_badge_list` - List badge types
- `ol_badge_get` - Get badge type details
- `ol_badge_update` - Update badge type configuration
- `ol_badge_get_member_badges` - Get badges earned by member

### Analytics (9 tools)
- `ol_analytics_tiers` - Get tier distribution with member counts
- `ol_analytics_members` - Get member statistics (new, active, inactive)
- `ol_analytics_points` - Get points statistics (issued, spent, expired)
- `ol_analytics_transactions` - Get transaction statistics
- `ol_analytics_referrals` - Get referral program statistics
- `ol_analytics_campaigns` - Get campaign performance metrics
- `ol_analytics_dashboard` - Get dashboard overview metrics
- `ol_analytics_units` - Get wallet-specific metrics
- `ol_analytics_campaign_detail` - Get detailed campaign analytics

### Admin Users (6 tools)
- `ol_admin_list` - List admin users
- `ol_admin_create` - Create admin user
- `ol_admin_get` - Get admin user details
- `ol_admin_update` - Update admin user profile
- `ol_admin_change_password` - Change admin password
- `ol_admin_get_permissions` - Get admin permissions

### Roles/ACL (6 tools)
- `ol_role_list` - List roles
- `ol_role_create` - Create role with permissions
- `ol_role_get` - Get role details
- `ol_role_update` - Update role
- `ol_role_delete` - Delete role
- `ol_acl_get_resources` - Get available ACL resources and actions

### API Keys (3 tools)
- `ol_apikey_create` - Create API key (token shown once!)
- `ol_apikey_list` - List API keys for admin
- `ol_apikey_delete` - Delete API key

### Audit Logs (2 tools)
- `ol_audit_list` - List audit log entries
- `ol_audit_export` - Export audit logs

### Stores (4 tools)
- `ol_store_list` - List stores
- `ol_store_create` - Create store for multi-tenancy
- `ol_store_get` - Get store details
- `ol_store_update` - Update store configuration

### Webhooks (6 tools)
- `ol_webhook_list` - List webhook subscriptions
- `ol_webhook_create` - Create webhook subscription for event notifications
- `ol_webhook_get` - Get webhook subscription details
- `ol_webhook_update` - Update webhook subscription
- `ol_webhook_delete` - Delete webhook subscription
- `ol_webhook_events` - List available webhook event types

### Import (3 tools)
- `ol_import_create` - Create bulk import from CSV
- `ol_import_list` - List imports with status
- `ol_import_get` - Get import details and item statuses

### Export (4 tools)
- `ol_export_create` - Create data export (async)
- `ol_export_list` - List exports with status
- `ol_export_get` - Get export status and details
- `ol_export_download` - Download export CSV (when status='done')

---

## Example Workflows

### 1. Create 3-Tier Loyalty Program

```
ol_wallet_type_list
// Note: conditions use `attribute` (not `type`) and walletType expects the wallet CODE (e.g., "default"), not the UUID.
ol_tierset_create({ name: "VIP Program", conditions: [{ attribute: "activeUnits", walletType: "points" }] })
ol_tierset_get({ tierSetId: "..." })
ol_tierset_update_tiers({
  tierSetId: "...",
  tiers: [
    { name: "Bronze", conditions: [{ conditionId: "xxx", value: 400 }] },
    { name: "Silver", conditions: [{ conditionId: "xxx", value: 800 }] },
    { name: "Gold", conditions: [{ conditionId: "xxx", value: 1200 }] }
  ]
})
```

### 2. Full Member Lifecycle

```
// Register member
ol_member_create({ email: "john@example.com", firstName: "John", lastName: "Doe" })

// Add welcome bonus
ol_points_add({ memberId: "...", points: 100, comment: "Welcome bonus" })

// Record purchase (auto-earns points via campaigns)
ol_transaction_create({
  header: { documentNumber: "INV-001", purchasedAt: "2024-01-15T10:00:00Z" },
  items: [{ sku: "PROD-1", name: "Widget", grossValue: 99.99, category: "Electronics" }],
  customerData: { email: "john@example.com" }
})

// Check tier progress
ol_member_get_tier_progress({ memberId: "..." })
```

### 3. Reward Redemption Flow

```
// List available rewards
ol_reward_list({ active: true })

// Check member balance
ol_points_get_balance({ memberId: "..." })

// Purchase reward (deducts points, returns coupon code)
ol_reward_buy({ rewardId: "...", memberId: "..." })

// Later: mark coupon as used
ol_reward_redeem({ memberId: "...", couponCode: "COUP-ABC123" })
```

### 4. Assign Unmatched Transaction

```
// Find unmatched transactions
ol_transaction_list({ matched: false })

// Assign to member (triggers point campaigns)
ol_transaction_assign_member({ documentNumber: "INV-999", loyaltyCardNumber: "CARD-123" })
```

### 5. Create Double Points Campaign for Gold Tier

```
// First, find the Gold tier level ID
ol_tierset_get_tiers({ tierSetId: "..." })

// Create a segment targeting Gold tier members
ol_segment_create({
  name: "Gold Members",
  parts: [{
    criteria: [{
      type: "tier",
      tierIds: ["gold-level-id"]
    }]
  }]
})

// Create campaign with double points effect
ol_campaign_create({
  type: "direct",
  trigger: "transaction",
  translations: { en: { name: "Double Points for Gold", description: "Gold members earn 2x points" } },
  // Required: activity.startsAt, rules[].name. Use effects[].effect (not type). pointsRule is a STRING expression (not an object).
  activity: { startsAt: "2024-01-01T00:00:00Z" },
  rules: [{
    name: "Double points",
    effects: [{
      effect: "give_points",
      pointsRule: "transaction.grossValue * 2"
    }]
  }],
  audience: {
    target: "segment",
    segments: ["segment-id"]
  },
  active: true
})

// Test the campaign before it triggers
ol_campaign_simulate({
  trigger: "transaction",
  transaction: { grossValue: 100 },
  customer: { email: "gold-member@example.com" }
})
```

### 6. Create VIP Segment Based on Transaction Count

```
// Create segment for members with 10+ transactions
ol_segment_create({
  name: "VIP Customers",
  description: "Members with 10 or more purchases",
  parts: [{
    criteria: [{
      type: "transaction_count",
      min: 10
    }]
  }],
  active: true
})

// Check segment membership
ol_segment_get_members({ segmentId: "..." })

// Use for campaign targeting
ol_campaign_create({
  type: "direct",
  trigger: "transaction",
  translations: { en: { name: "VIP Bonus" } },
  activity: { startsAt: "2024-01-01T00:00:00Z" },
  rules: [{
    name: "VIP Bonus Points",
    effects: [{ effect: "give_points", pointsRule: "50" }]
  }],
  audience: { target: "segment", segments: ["vip-segment-id"] },
  active: true
})
```

### 7. Create Purchase Achievement with Badge

```
// Create an achievement for making 5 purchases
ol_achievement_create({
  translations: { en: { name: "Frequent Shopper", description: "Make 5 purchases" } },
  rules: [{
    type: "direct",
    trigger: "transaction",
    aggregation: { type: "quantity" },
    completeRule: {
      periodGoal: 5,
      period: { type: "day", consecutive: 1 }
    }
  }],
  badgeTypeId: "shopper-badge-id",
  active: true
})

// Check member progress
ol_achievement_get_member_progress({ memberId: "...", achievementId: "..." })

// List all member achievements and badges
ol_achievement_list_member_achievements({ memberId: "..." })
ol_badge_get_member_badges({ memberId: "..." })
```

### 8. Segment Logic: OR vs AND

```
// Parts use OR logic - member matches if ANY part matches
// Criteria within parts use AND logic - must match ALL criteria in that part

// Example: (10+ transactions) OR (5-9 transactions)
ol_segment_create({
  name: "High Value Members",
  parts: [
    {
      // Part 1: Frequent shoppers
      criteria: [
        { type: "transaction_count", min: 10, max: 999999 }
      ]
    },
    {
      // Part 2: Moderately frequent shoppers (OR with Part 1)
      criteria: [
        { type: "transaction_count", min: 5, max: 9 }
      ]
    }
  ]
})
```

### 9. Create Read-Only Analyst Role

```
// Discover available ACL resources and actions
ol_acl_get_resources()

// Create a role with VIEW-only permissions
ol_role_create({
  name: "Analyst",
  permissions: [
    { resource: "ANALYTICS", access: "VIEW" },
    { resource: "MEMBER", access: "VIEW" },
    { resource: "TRANSACTION", access: "VIEW" },
    { resource: "CAMPAIGN", access: "VIEW" }
  ]
})

// Create admin with analyst role
ol_admin_create({
  email: "analyst@company.com",
  password: "SecurePass123!",
  firstName: "Data",
  lastName: "Analyst",
  roles: ["analyst-role-id"]
})
```

### 10. Generate API Key for Integration

```
// Get admin to create API key for
ol_admin_list({ email: "integration@company.com" })

// Create API key - CRITICAL: Save the token immediately!
ol_apikey_create({
  adminId: "admin-uuid",
  name: "CRM Integration Key",
  expirationDate: "2025-12-31"
})
// Response includes token that is ONLY shown once

// List API keys (tokens not shown)
ol_apikey_list({ adminId: "admin-uuid" })
```

### 11. Analyze Program Performance

```
// Get high-level dashboard metrics
ol_analytics_dashboard()

// Analyze tier distribution
ol_analytics_tiers({ dateFrom: "2024-01-01", dateTo: "2024-12-31" })

// Check points economy
ol_analytics_points({ dateFrom: "2024-01-01", dateTo: "2024-12-31" })

// Analyze specific campaign
ol_analytics_campaign_detail({ campaignId: "campaign-uuid" })

// Get wallet-specific metrics
ol_analytics_units({ walletTypeCode: "points" })
```

### 12. Audit User Actions

```
// List recent audit entries
ol_audit_list({ perPage: 50 })

// Filter by specific user
ol_audit_list({ username: "admin@company.com" })

// Filter by entity type and date range
ol_audit_list({
  entityType: "MEMBER",
  dateFrom: "2024-01-01",
  dateTo: "2024-01-31"
})

// Export audit logs for compliance
ol_audit_export({
  dateFrom: "2024-01-01",
  dateTo: "2024-12-31"
})
```

### 13. Multi-Tenant Store Setup

```
// Create a new store for a region
ol_store_create({
  code: "EU",
  name: "European Store",
  currency: "EUR",
  active: true
})

// List all stores
ol_store_list()

// Use storeCode in subsequent operations
ol_member_create({
  email: "customer@eu.example.com",
  firstName: "Jean",
  lastName: "Dupont",
  storeCode: "EU"
})
```

### 14. Subscribe to Member Events for CRM Sync

```
// Discover available event types
ol_webhook_events()

// Subscribe to member creation events
ol_webhook_create({
  eventName: "member.created",
  url: "https://crm.example.com/webhooks/loyalty",
  headers: [
    { headerName: "Authorization", headerValue: "Bearer crm-token" }
  ]
})

// List current subscriptions
ol_webhook_list()

// Update subscription URL
ol_webhook_update({
  webhookSubscriptionId: "...",
  url: "https://crm-v2.example.com/webhooks/loyalty"
})
```

### 15. Bulk Import Members from CSV

```
// Create import with CSV content
ol_import_create({
  type: "member",
  fileContent: "email,firstName,lastName\njohn@example.com,John,Doe\njane@example.com,Jane,Smith",
  fileName: "members.csv"
})

// Poll import status
ol_import_list({ type: "member" })

// Check individual item statuses
ol_import_get({ importId: "..." })
```

### 16. Export Campaign Codes and Download

```
// Create export for campaign codes
ol_export_create({
  type: "campaignCode",
  filters: { campaignId: "campaign-uuid" }
})

// Poll until status is 'done'
ol_export_get({ exportId: "..." })

// Download the CSV file
ol_export_download({ exportId: "..." })
```

### 17. Bulk Add Points via Import

```
// Create import for adding points to multiple members
ol_import_create({
  type: "unitTransferAdding",
  fileContent: "loyaltyCardNumber,points,comment\nCARD-001,500,Promotion bonus\nCARD-002,500,Promotion bonus"
})

// Check import progress
ol_import_get({ importId: "..." })
```

---

## Links

- **GitHub**: [OpenLoyalty/openloyalty-mcp](https://github.com/OpenLoyalty/openloyalty-mcp)
- **Open Loyalty**: [openloyalty.io](https://openloyalty.io)
- **MCP Protocol**: [modelcontextprotocol.io](https://modelcontextprotocol.io)

## License

MIT