Model Context Protocol (MCP) AI Integration
Status: Production Ready
Version: 1.0.0
Last Updated: December 2024
Overview
The Model Context Protocol (MCP) integration enables AI assistants like Claude (via Cursor IDE) to access WarmlyYours content through semantic search. This allows AI to find relevant product information, FAQs, installation guides, images, and more using natural language queries.
MCP is an open standard developed by Anthropic for connecting AI models to external tools and data sources. Learn more at modelcontextprotocol.io.
Architecture
┌─────────────────┐ HTTPS/SSE ┌──────────────────┐
│ AI Client │◄──────────────────►│ MCP Server │
│ (Cursor/Claude)│ │ (FastMCP gem) │
└─────────────────┘ └────────┬─────────┘
│
┌────────▼─────────┐
│ MCP Tools │
│ - semantic_search│
│ - find_faqs │
│ - find_images │
│ - find_publications│
│ - find_showcases│
│ - find_reviews │
└────────┬─────────┘
│
┌────────▼─────────┐
│ pgvector DB │
│ (Embeddings) │
└──────────────────┘
Available Tools
| Tool | Description |
|---|---|
semantic_search |
Search all content with natural language queries |
find_faqs |
Find FAQ articles by topic or product line |
find_images |
Find product images and installation photos |
find_publications |
Find PDFs, manuals, and datasheets |
find_showcases |
Find customer installation galleries |
find_reviews |
Find customer reviews from Reviews.io |
Endpoints
MCP is only accessible via the API subdomain (api.warmlyyours.com).
| Endpoint | Method | Description |
|---|---|---|
https://api.warmlyyours.com/mcp/sse |
GET | Server-Sent Events for real-time communication |
https://api.warmlyyours.com/mcp/messages |
POST | JSON-RPC message handler for tool calls |
Note: Requests to other subdomains (www, crm) will be rejected even with valid tokens.
Authentication
Requirements
- Employee Account - Only employees can access MCP
- mcp_access Role - Must have the
mcp_accessrole (admins have this by default) - API Token - A valid, non-expired API token
Token Generation
Via Web UI
- Navigate to CRM → Employees → [Employee Name]
- Click the System tab
- In the API Tokens panel, click Create Token
- Enter a name (e.g., "Cursor MCP") and expiration
- Copy the token immediately - it won't be shown again!
Via Rails Console
# Find the employee
employee = Employee.find_by(email: 'your.email@warmlyyours.com')
# Check if they have MCP access
employee.account.can_access_mcp?
# => true (if admin or has mcp_access role)
# Generate a token
token = employee.account.api_authentications.create!(
name: 'Cursor MCP',
expires_in: '3 months'
)
puts "Token: #{token.api_authentication_token}"
# Token: abc123xyz...
Token Management
- View tokens:
/employees/:id/api_tokens - Revoke tokens: Click "Revoke" button on any active token
- Auto-revocation: All tokens are automatically revoked if the account is disabled
Token Expiration Options
| Duration | Use Case |
|---|---|
| 1 hour | Testing/debugging |
| 1 day | Temporary access |
| 1 week | Short-term projects |
| 1 month | Regular use |
| 3 months | Recommended for daily use |
| 6 months | Long-term development |
| 1 year | Extended access |
| Never | Permanent (use sparingly) |
Client Configuration
Cursor IDE
Create or edit ~/.cursor/mcp.json:
{
"mcpServers": {
"heatwave": {
"url": "https://api.warmlyyours.com/mcp/sse",
"headers": {
"Authorization": "Bearer YOUR_API_TOKEN_HERE"
}
}
}
}
After saving, restart Cursor. The MCP server will appear in the available tools.
Claude Desktop (if supported)
{
"mcpServers": {
"heatwave": {
"command": "curl",
"args": [
"-H", "Authorization: Bearer YOUR_API_TOKEN_HERE",
"https://api.warmlyyours.com/mcp/sse"
]
}
}
}
Local Development
For development, use api.warmlyyours.me:3000:
{
"mcpServers": {
"heatwave-dev": {
"url": "https://api.warmlyyours.me:3000/mcp/sse",
"headers": {
"Authorization": "Bearer YOUR_DEV_TOKEN"
}
}
}
}
Usage Examples
Once connected, the AI assistant can call these tools naturally:
Semantic Search
User: Find information about installing floor heating under tile
AI: [Calls semantic_search with query "installing floor heating under tile"]
Find FAQs
User: What are the voltage requirements for snow melting systems?
AI: [Calls find_faqs with query "voltage requirements snow melting"]
Find Publications
User: Get me the TempZone cable installation guide
AI: [Calls find_publications with query "TempZone cable installation guide"]
Find Images
User: Show me bathroom floor heating installation photos
AI: [Calls find_images with query "bathroom floor heating installation"]
Security
Access Control
| Role | MCP Access |
|---|---|
admin |
✅ Automatic |
mcp_access |
✅ Explicit |
| Other roles | ❌ No access |
Security Features
- API subdomain only - MCP endpoints only respond on
api.warmlyyours.com - Token-based authentication - No session cookies, no CSRF concerns
- Expiring tokens - All tokens have configurable expiration
- Revocation - Tokens can be instantly revoked
- Account lockout - All tokens revoked when account is disabled
- Audit trail - Token creation and revocation are tracked
- Role verification - Double-checks
mcp_accessrole on every request
Best Practices
- Use descriptive token names (e.g., "Cursor MCP - MacBook Pro")
- Set reasonable expiration times (3 months recommended)
- Revoke tokens for devices you no longer use
- Don't share tokens between team members
- Rotate tokens periodically
Troubleshooting
"Unauthenticated request" in logs
Cause: Missing or invalid token, OR wrong subdomain
Fix:
- Ensure you're using
api.warmlyyours.com(notcrmorwww) - Check that your
Authorizationheader is correct - Verify the token hasn't expired or been revoked
"No tools available" in AI client
Cause: Token is valid but user lacks mcp_access role
Fix: Ask an admin to assign the mcp_access role to your account
Connection timeout
Cause: Network issues or server not running
Fix:
- Check if the server is accessible:
curl https://api.warmlyyours.com/mcp/sse - Verify VPN connection if required
- Check firewall settings
Token not working after creation
Cause: Token was copied incorrectly or has special characters
Fix: Generate a new token and copy it directly from the confirmation screen
"Wrong subdomain" or silent auth failure
Cause: Using crm.warmlyyours.com or www.warmlyyours.com
Fix: Change your MCP config URL to use api.warmlyyours.com
Technical Implementation
Files
| File | Purpose |
|---|---|
config/initializers/fast_mcp.rb |
MCP server configuration |
app/mcp/application_tool.rb |
Base class for MCP tools |
app/mcp/application_resource.rb |
Base class for MCP resources |
app/mcp/mcp_authenticator.rb |
Token validation and authorization |
app/mcp/tools/*.rb |
Individual tool implementations |
app/controllers/crm/api_tokens_controller.rb |
Token management UI |
app/views/crm/api_tokens/*.erb |
Token management views |
Dependencies
fast_mcpgem - MCP server implementationpgvector- Vector similarity search in PostgreSQLruby_llm- LLM API integration for embeddings
Adding New Tools
- Create a new file in
app/mcp/tools/:
# app/mcp/tools/find_something_tool.rb
module Tools
class FindSomethingTool < ApplicationTool
tool_name 'find_something'
description 'Description of what this tool does'
arguments do
required(:query).filled(:string).description('Search query')
optional(:limit).filled(:integer).description('Max results')
end
def call(query:, limit: 10)
# Implementation
results = SomeModel.search(query).limit(limit)
{
query: query,
total_results: results.size,
results: results.map { |r| format_result(r) }
}
end
private
def format_result(result)
{ id: result.id, name: result.name }
end
end
end
- The tool will be automatically registered on server restart.
Related Documentation
- MCP Servers Setup Guide - Complete setup for Cursor & Claude Desktop
- Semantic Search Embeddings - How embeddings are generated and stored
- MCP Database Access - PostgreSQL MCP servers
Changelog
v1.0.0 (December 2024)
- Initial MCP server implementation
- 6 content discovery tools
- Token-based authentication
- Employee management UI for tokens
- Auto-revocation on account disable