CDP (Customer Data Platform) API MCP Server for user management operations
npm install @olbrain/cdp-api-mcpA Model Context Protocol (MCP) server for interacting with CDP (Customer Data Platform) APIs. Provides complete CRUD operations for user management.
Status: ✅ Production Ready | Default Server: https://converse.showroom.lumegalabs.com | Tools: 6
The CDP API MCP server supports autonomous, template-based execution for session-aware workflows. This enables the agent to automatically identify users at conversation start without requiring explicit tool calls.
1. Session Start: When a conversation begins, the agent automatically executes cdp_get_current_user
2. User Identification: The server identifies the user from session data (email, phone, or user_id)
3. CDP Lookup: Searches the CDP database for the matching user profile
4. Profile Retrieval: Returns user data including interests, attributes, and purchase history
5. Personalization: Agent uses this data for personalized recommendations and interactions
The system identifies users using this priority order:
1. User ID - Most reliable, direct database lookup
2. OTP Authenticated Phone - Verified phone number from OTP authentication
3. Verified Email - Email verified during registration
4. Mobile Number - User profile mobile number
5. WhatsApp Channel ID - For WhatsApp conversations
``
Customer: "Hi, I'm looking for products"
→ Agent automatically calls cdp_get_current_user
→ Identifies user via session email/phone
→ Retrieves: {name: "John", interests: ["electronics", "laptops"], budget: "$1000-$2000"}
Agent: "Hi John! I see you're interested in electronics.
Based on your budget, I can recommend some great laptops.
How can I help you today?"
`
Enable/disable auto-identification in server configuration:
`json`
{
"CDP_AUTO_IDENTIFY": true
}
When enabled (default), the agent automatically retrieves user profiles at conversation start.
The CDP server integrates with Firestore agent_sessions collection to access:
- User authentication data
- Session metadata
- Verified contact information
- Channel-specific identifiers
Note: In MCP stdio mode (direct testing), session awareness features are disabled. Full autonomous execution requires integration with olbrain-studio backend.
The CDP MCP server includes a Sales Agent role with automatic prompt template injection. When you select the "Sales Agent" role in olbrain-studio, the backend automatically appends specialized instructions to the agent's system prompt.
1. Role Selection: User selects "Sales Agent" role when configuring an agent
2. Backend Injection: olbrain-studio backend automatically appends the sales agent template to the system prompt
3. Automatic Behavior: Agent automatically calls cdp_get_current_user at every conversation start
4. No User Configuration: Template is invisible to users - works automatically
When the Sales Agent role is active, the agent will:
✅ Auto-identify customers at conversation start using CDP data
✅ Personalize greetings with customer name and interests
✅ Recommend products based on customer preferences and budget
✅ Update profiles as new customer preferences and interests are discovered
✅ Follow sales workflow from greeting → needs discovery → recommendation → purchase
The template instructs the agent to follow this workflow:
``
1. Session Start → Auto-call cdp_get_current_user
2. Personalized Greeting → "Hi John! I see you're interested in laptops..."
3. Needs Discovery → Listen and match with CDP profile
4. Product Recommendation → Use BYS API + CDP preferences
5. Purchase Flow → BYS checkout
6. Follow-up → Update CDP with latest preferences and interests
#### Returning Customer (Found in CDP)
`
[Agent automatically identifies user from CDP]
Agent: "Hi Sarah! Great to see you again. I see you're interested in
electronics. How can I help you today?"
Customer: "I need a new laptop for work"
Agent: [Checks Sarah's CDP profile: budget $1000-$2000, prefers Dell/Lenovo]
[Searches BYS product catalog with filters]
"Based on your budget and preferences, I have these options:
1. Dell XPS 13 - $1,299 (your preferred brand)
2. Lenovo ThinkPad - $1,199 (great for work)
Which would you like to know more about?"
Customer: "Tell me about the Dell XPS"
Agent: [Provides details...]
"Would you like to purchase this?"
Customer: "Yes please"
Agent: [BYS API: Add to cart, checkout]
[Updates CDP user: adds "Dell XPS 13" to interests]
"Order confirmed! You'll receive tracking details shortly."
`
#### New Customer (NOT Found in CDP)
`
[Agent calls cdp_get_current_user - returns "user not found"]
Agent: "Hi! Welcome! I'm here to help you find exactly what you need.
What are you looking for today?"
Customer: "I need a laptop for gaming"
Agent: "Gaming laptops, excellent! I can help with that.
By the way, I'm Alex. What should I call you?"
Customer: "I'm Mike"
Agent: "Nice to meet you, Mike! What's your budget range for the gaming laptop?"
Customer: "Around $1500"
Agent: [Searches products]
"Perfect! I have great options. Do you have any preferred brands?"
Customer: "I like ASUS"
Agent: "Excellent choice! Before I show you the best ASUS gaming laptops,
mind if I email you the details? What's your email?"
Customer: "mike@example.com"
Agent: [Creates CDP profile with cdp_create_user:
full_name="Mike", email_id="mike@example.com", msisdn="+91..."]
[Updates profile to add first interest:
product_required="gaming laptops"]
[Updates profile to add second interest:
product_required="ASUS", previous_interest="gaming laptops"]
"Thanks Mike! Here are the top ASUS gaming laptops in your range..."
[Continues with recommendations]
`
Key Difference: New customers experience natural, conversational data collection without forms or registration prompts.
The Sales Agent template is configured in server_config.json:
`json`
"prompt_templates": {
"sales_agent": {
"file": "templates/sales_agent_template.txt",
"role_name": "Sales Agent",
"injection_point": "append",
"visibility": "backend_only"
}
}
Key Points:
- Template is backend-only (not visible to users)
- Automatically injected when role is selected
- No manual configuration needed
- Works seamlessly with CDP auto-identification
The Sales Agent template is stored in Firebase Firestore for dynamic loading and updates:
- Collection: mcp_server_templatescdp-api-sales-agent
- Document: templates/sales_agent_template.txt
- Fallback: (if Firestore unavailable)
Benefits:
- ✅ Update templates without redeploying MCP server
- ✅ Version control and audit trail
- ✅ Instant rollout to all agents
- ✅ A/B testing capabilities
- ✅ Centralized management
For Backend Team:
See FIRESTORE_TEMPLATE_SETUP.md for:
- Initial upload process
- Loading implementation
- Update procedures
- Security configuration
1. Open any agent → Tools → MCP Servers
2. Search for "CDP API" in public servers
3. Click "Add to Agent"
4. Default configuration connects to production CDP server (https://converse.showroom.lumegalabs.com)
5. Start using: "Show me all users from the CDP"
`bash`
npx -y @olbrain/cdp-api-mcp@latest
bash
Clone the repository
git clone https://github.com/alchemist-ai/alchemist-public-tools.git
cd alchemist-public-tools/mcp_servers/cdp-apiInstall Node.js dependencies
npm installInstall Python dependencies
pip3 install -r requirements.txt
`Configuration
$3
The MCP server is pre-configured to connect to the production CDP server:
- URL:
https://converse.showroom.lumegalabs.com
- Authentication: Bearer token required
- Status: ✅ Online and verifiedNo configuration needed for default use!
$3
If you want to use your own CDP server:
#### Required Environment Variables
-
CDP_API_BASE_URL: Base URL of your CDP API server
- Default: https://converse.showroom.lumegalabs.com
- Example: http://your-cdp-server.com:8000#### Optional Environment Variables
-
API_AUTH_TOKEN: Bearer token for API authentication (if required)$3
When adding this MCP server to olbrain-studio:
1. Navigate to Tools → MCP Servers
2. Add new MCP server
3. Upload
server_config.json or manually configure:
- CDP API Base URL: Your CDP API endpoint
- API Authentication Token: (Optional) If your API requires authAvailable Tools
$3
#### 1.
cdp_create_user
Create a new user in the CDP.Parameters:
-
full_name (required): User's full name
- msisdn (required): Phone number in MSISDN format (e.g., +919876543210)
- email_id (optional): User's email address
- gender (optional): User's gender (e.g., 'MALE', 'FEMALE')
- date_of_birth (optional): Date of birth in DD/MM/YYYY format (e.g., 01/01/1995)
- client_id (optional): Client identifier for the userExample:
`json
{
"full_name": "John Doe",
"msisdn": "+919876543210",
"email_id": "john.doe@example.com",
"gender": "MALE",
"date_of_birth": "15/05/1990",
"client_id": "CLT001"
}
`Notes:
- ID is auto-generated by the system and should not be provided during creation
- To add interests, use
cdp_update_user after creation with the product_required and previous_interest fields (see "Working with User Interests" section)#### 2.
cdp_get_current_user
Get the current user's CDP profile based on session identification.Parameters: None (automatically identifies user from session)
Description:
This tool autonomously identifies the current user by:
- Extracting user identifier from session data (email, phone, or user_id)
- Searching CDP database for matching user
- Returning complete user profile with interests and attributes
Response:
`json
{
"success": true,
"message": "User identified successfully via email",
"data": {
"user_id": "user123456789",
"full_name": "John Doe",
"email": "john.doe@example.com",
"phone": "+919876543210",
"interests": [
{
"field": "product_interests",
"value": "electronics, laptops"
}
],
"custom_attributes": {
"budget_range": "$1000-$2000",
"preferred_brands": "Apple, Dell"
},
"matched_by": "email"
}
}
`Use Cases:
- Personalized product recommendations
- Customer service with user history
- Sales workflows with customer context
- Automatic user profile retrieval at conversation start
#### 3.
cdp_search_users
Search for users by email, phone, or name.Parameters:
-
email (optional): Email address to search for
- phone (optional): Phone number to search for (any format)
- name (optional): Name to search for (partial match supported)Description:
Use this tool when automatic user identification fails (
cdp_get_current_user returns error). Ask the customer for their email or phone number, then search the CDP database to see if they already have a profile before creating a new one.Response:
`json
{
"success": true,
"message": "Found 1 matching user(s)",
"data": [
{
"user_id": "user123456789",
"full_name": "John Doe",
"email": "john.doe@example.com",
"phone": "+919876543210",
"interests": ["laptops", "gaming"],
"budget_range": "$1500"
}
]
}
`When No Match Found:
`json
{
"success": false,
"error": "No users found matching search criteria",
"searched_with": {
"email": "john@example.com",
"phone": null,
"name": null
},
"message": "No users found. User may need to be created first."
}
`Use Cases:
- Manual user identification when session data unavailable
- Customer lookup by support agents
- Verify user existence before creating duplicate profiles
- Find returning customers who aren't logged in
Flow:
1.
cdp_get_current_user fails (no session identifier)
2. Agent asks: "May I have your email address?"
3. Agent calls: cdp_search_users(email="customer@example.com")
4. If found: Use existing profile
5. If not found: Proceed to create new user with cdp_create_user#### 4.
cdp_get_all_users
Get paginated list of all users.Parameters:
-
page (optional, default: 0): Page number (0-indexed)
- size (optional, default: 10): Number of items per page#### 5.
cdp_update_user
Update an existing user.Important: You must provide ALL mandatory fields (id, full_name, msisdn), not just the fields you want to change.
Parameters:
-
id (required): User ID
- full_name (required): User's full name (must include even if not changing)
- msisdn (required): User's phone number (must include even if not changing)
- email_id (optional): User's email address
- gender (optional): User's gender
- date_of_birth (optional): Date of birth in DD/MM/YYYY format
- client_id (optional): Client identifier
- product_required (optional): Current/latest product interest
- previous_interest (optional): Accumulated chain of past interests (format: "interest1 + interest2 + interest3")Example - Basic Update:
`json
{
"id": "user123456789",
"full_name": "John Updated Doe",
"msisdn": "+919876543210",
"email_id": "john.updated@example.com",
"gender": "MALE",
"date_of_birth": "15/05/1990",
"client_id": "CLT001"
}
`Example - Adding First Interest:
`json
{
"id": "user123456789",
"full_name": "John Doe",
"msisdn": "+919876543210",
"product_required": "electronics"
}
`Example - Adding Second Interest (Chain Pattern):
Assuming current state has
product_required: "electronics" and previous_interest: "":
`json
{
"id": "user123456789",
"full_name": "John Doe",
"msisdn": "+919876543210",
"product_required": "laptops",
"previous_interest": "electronics"
}
`Example - Adding Third Interest:
Assuming current state has
product_required: "laptops" and previous_interest: "electronics":
`json
{
"id": "user123456789",
"full_name": "John Doe",
"msisdn": "+919876543210",
"product_required": "gaming",
"previous_interest": "electronics + laptops"
}
`Note: See the "Working with User Interests" section above for complete details on the two-field chain mechanism.
#### 6.
cdp_delete_user
Delete a user by ID.Parameters:
-
user_id (required): User ID to deleteWorking with User Interests
User interests use a two-field chain mechanism:
product_required (current interest) and previous_interest (accumulated past interests).$3
Two Fields:
-
product_required: Holds the current/latest product interest
- previous_interest: Accumulates all previous interests in a chainThe Chain Pattern:
When adding a new interest, you move the old
product_required value into the previous_interest chain:`
Current State:
product_required: "example"
previous_interest: "apple"To Add New Interest "laptops":
product_required: "laptops" ← Set to new interest
previous_interest: "apple + example" ← Concatenate: old_previous + old_product_required
`$3
Step 1: Create User with First Interest
`javascript
cdp_create_user({
full_name: "John Doe",
msisdn: "+919876543210",
email_id: "john@example.com"
})
// Then update to add first interest:
cdp_update_user({
id: "user123...",
full_name: "John Doe",
msisdn: "+919876543210",
product_required: "electronics"
})// State:
// product_required: "electronics"
// previous_interest: "" (empty)
`Step 2: Add Second Interest
`javascript
cdp_update_user({
id: "user123...",
full_name: "John Doe",
msisdn: "+919876543210",
product_required: "laptops", // ← New interest
previous_interest: "electronics" // ← Move old product_required here
})// State:
// product_required: "laptops"
// previous_interest: "electronics"
`Step 3: Add Third Interest
`javascript
cdp_update_user({
id: "user123...",
full_name: "John Doe",
msisdn: "+919876543210",
product_required: "gaming", // ← New interest
previous_interest: "electronics + laptops" // ← Concatenate: old_previous + old_product_required
})// State:
// product_required: "gaming"
// previous_interest: "electronics + laptops"
`Step 4: Add Fourth Interest
`javascript
cdp_update_user({
id: "user123...",
full_name: "John Doe",
msisdn: "+919876543210",
product_required: "smartphones", // ← New interest
previous_interest: "electronics + laptops + gaming" // ← Concatenate chain
})// State:
// product_required: "smartphones"
// previous_interest: "electronics + laptops + gaming"
`$3
✅ DO:
- Use
product_required for the current/latest interest
- Use previous_interest to accumulate the chain of past interests
- Concatenate with + (space + plus + space) as the separator
- Always read the current values before updating to avoid overwriting❌ DON'T:
- Don't overwrite
previous_interest without including old values
- Don't pass arrays (only string concatenation supported)
- Don't add interests during user creation (use update after creation)Chain Format:
`
previous_interest: "interest1 + interest2 + interest3 + interest4"
`$3
When retrieving user data, you'll see both fields:
`json
{
"product_required": "smartphones",
"previous_interest": "electronics + laptops + gaming"
}
`To get the full interest history, combine them:
`
All interests: previous_interest.split(" + ") + [product_required]
Result: ["electronics", "laptops", "gaming", "smartphones"]
`API Format
$3
The CDP API uses standard snake_case format for all field names.
Format: snake_case (lowercase with underscores)
- Used consistently across all API requests and responses
- Example:
full_name, email_id, msisdn, date_of_birth, client_id, product_required, previous_interestField Names:
| Field Name | Description |
|-----------|-------------|
|
full_name | User's full name |
| email_id | User's email address |
| msisdn | User's phone number in MSISDN format |
| gender | User's gender |
| date_of_birth | Date of birth (DD/MM/YYYY format) |
| client_id | Client identifier |
| id | User ID |
| product_required | Current/latest product interest |
| previous_interest | Accumulated chain of past interests |Example API Request:
`json
{
"full_name": "John Doe",
"email_id": "john@example.com",
"msisdn": "+919876543210",
"gender": "MALE",
"date_of_birth": "15/05/1990",
"client_id": "CLT001",
"product_required": "laptops",
"previous_interest": "electronics"
}
`All fields use snake_case consistently. No conversion or special formatting is required.
Testing
To test the CDP API MCP server:
1. Ensure your CDP API is running:
`bash
# Your CDP API should be accessible at the configured base URL
curl https://converse.showroom.lumegalabs.com/cdp-user-api/users
`2. Test the MCP server:
`bash
# Set environment variables
export CDP_API_BASE_URL=https://converse.showroom.lumegalabs.com # Run the server
node index.js
`3. Send MCP protocol messages via stdin:
`json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
`Development
$3
`
cdp-api/
├── index.js # Node.js entry point
├── package.json # NPM package configuration
├── requirements.txt # Python dependencies
├── server_config.json # MCP server configuration
├── README.md # This file
├── templates/
│ └── sales_agent_template.txt # Sales Agent role template (backend-injected)
└── src/
├── server.py # Main MCP server implementation
├── cdp_client.py # CDP API client
├── cdp_executor.py # Template execution engine (session-aware)
└── tools/
└── user_tools.py # User management tools
`$3
1. Define tool in
user_tools.py
2. Create async handler function
3. Add handler to TOOL_HANDLERS dict
4. Add tool definition to TOOLS listRequirements
- Node.js: >= 16.0.0
- Python: >= 3.7
- Python Package: requests >= 2.31.0
Troubleshooting
$3
- Verify CDP_API_BASE_URL environment variable is set
- Check that Python 3 is installed and accessible
- Ensure requirements.txt dependencies are installed$3
- Verify CDP API is running and accessible
- Check base URL format (should include protocol: http:// or https://)
- If using authentication, verify API_AUTH_TOKEN` is correctThis MCP server is connected to a live production CDP server with real data:
- 8+ users already in system
- Real-time updates supported
- Authentication required for production server
See DEPLOYMENT.md for complete deployment guide.
The server has been tested with:
- ✅ User creation with interests field (both camelCase and snake_case formats)
- ✅ User retrieval with pagination
- ✅ User updates including interests
- ✅ User deletions
- ✅ Current user identification from session
- ✅ User search by email, phone, or name
- ✅ Real production CDP server integration
- DEPLOYMENT.md - Complete deployment guide
- README.md - This file
- server_config.json - MCP server configuration
MIT
Alchemist
https://github.com/alchemist-ai/alchemist-public-tools
For issues and feature requests, please visit the GitHub repository.