MCP Server (AI-Ready Data Layer)
Drizzle Cube includes a built-in MCP server that lets AI agents like Claude, ChatGPT, and n8n query your semantic layer directly. The server follows the Model Context Protocol specification and exposes tools for discovering cubes, validating queries, and executing them.
MCP Server Endpoint
Section titled “MCP Server Endpoint”All framework adapters expose an MCP server at /mcp:
https://your-app.com/mcpThis endpoint implements the full MCP specification including:
- Tools - Functions the AI can call
- Prompts - Pre-built prompts for common tasks
- Server-Sent Events (SSE) - For streaming responses
Available MCP Tools
Section titled “Available MCP Tools”| Tool | Purpose |
|---|---|
drizzle_cube_discover | Find relevant cubes based on topic or intent |
drizzle_cube_validate | Validate queries and get auto-corrections |
drizzle_cube_load | Execute queries and return results |
Connecting AI Tools
Section titled “Connecting AI Tools”Claude Desktop
Section titled “Claude Desktop”Add to your claude_desktop_config.json:
{ "mcpServers": { "your-app-analytics": { "command": "npx", "args": ["-y", "@anthropic/mcp-remote", "https://your-app.com/mcp"] } }}Claude.ai (Web)
Section titled “Claude.ai (Web)”- Go to Settings → Connectors → Add Connector
- Enter your MCP server URL:
https://your-app.com/mcp - The tools will be available in your conversations
ChatGPT
Section titled “ChatGPT”- Go to Settings → Connectors → Advanced → Developer Mode
- Add your MCP server URL:
https://your-app.com/mcp - The tools will be available in ChatGPT
Use the MCP Client node:
- Add an MCP Client node to your workflow
- Set the server URL:
https://your-app.com/mcp - Connect it to an AI Agent node
See n8n MCP Client documentation for details.
The AI Workflow
Section titled “The AI Workflow”When an AI agent connects to your MCP server, it typically follows this workflow:
User: "Show me average salary by department" │ ▼┌─────────────────────────────────────────────────────┐│ 1. drizzle_cube_discover ││ Find cubes related to "salary" and "department" ││ → Returns: Employees, Departments cubes with ││ suggested measures and dimensions │└─────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────┐│ 2. AI builds query using metadata ││ The AI uses cube metadata to construct a query ││ → Query: { measures: ['Employees.avgSalary'], ││ dimensions: ['Departments.name'] } │└─────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────┐│ 3. drizzle_cube_validate (optional) ││ Check query validity, get corrections if needed ││ → Returns: { isValid: true, correctedQuery } │└─────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────┐│ 4. drizzle_cube_load ││ Execute query with security context ││ → Returns: { data: [...], annotation: {...} } │└─────────────────────────────────────────────────────┘Tool Reference
Section titled “Tool Reference”drizzle_cube_discover
Section titled “drizzle_cube_discover”Find cubes relevant to a topic or intent.
// Parameters{ "topic": "salary", "intent": "I want to analyze compensation", "limit": 5, "minScore": 0.3}
// Response{ "cubes": [ { "cube": "Employees", "relevanceScore": 0.85, "matchedOn": ["measure:avgSalary", "measure:totalSalary"], "suggestedMeasures": ["Employees.avgSalary", "Employees.totalSalary"], "suggestedDimensions": ["Employees.department", "Employees.location"] } ]}drizzle_cube_validate
Section titled “drizzle_cube_validate”Validate a query and get helpful corrections.
// Parameters{ "query": { "measures": ["Employees.cont"], "dimensions": ["Departments.nam"] }}
// Response{ "isValid": false, "errors": [ "Unknown measure 'Employees.cont' - did you mean 'Employees.count'?", "Unknown dimension 'Departments.nam' - did you mean 'Departments.name'?" ], "correctedQuery": { "measures": ["Employees.count"], "dimensions": ["Departments.name"] }}drizzle_cube_load
Section titled “drizzle_cube_load”Execute a query and return results.
// Parameters{ "query": { "measures": ["Employees.count", "Employees.avgSalary"], "dimensions": ["Departments.name"] }}
// Response{ "data": [ { "Departments.name": "Engineering", "Employees.count": 45, "Employees.avgSalary": 125000 }, { "Departments.name": "Sales", "Employees.count": 32, "Employees.avgSalary": 85000 } ], "annotation": { "measures": { "Employees.count": { "title": "Total Employees", "type": "count" }, "Employees.avgSalary": { "title": "Average Salary", "type": "avg" } }, "dimensions": { "Departments.name": { "title": "Department Name", "type": "string" } } }}Configuration
Section titled “Configuration”Disabling MCP
Section titled “Disabling MCP”If you don’t want the MCP server exposed:
createCubeRouter({ // ... other options mcp: { enabled: false }})Selective Tool Exposure
Section titled “Selective Tool Exposure”Expose only specific MCP tools:
createCubeRouter({ // ... other options mcp: { enabled: true, tools: ['discover', 'validate', 'load'] // Only expose these }})Origin Restrictions
Section titled “Origin Restrictions”Restrict which origins can connect to your MCP server:
createCubeRouter({ // ... other options mcp: { enabled: true, allowedOrigins: ['https://claude.ai', 'https://chat.openai.com'] }})Security & Authentication
Section titled “Security & Authentication”Important: The MCP server does not include built-in authentication. You are responsible for adding authentication middleware, just like with the standard Cube API routes.
Authentication Is Your Responsibility
Section titled “Authentication Is Your Responsibility”Apply authentication middleware before mounting the cube router:
import { createCubeRouter } from 'drizzle-cube/adapters/express'import { authMiddleware } from './auth'
const app = express()
// Apply authentication BEFORE mounting the cube routerapp.use(authMiddleware)
// Now both /cubejs-api/v1/* AND /mcp require authenticationconst cubeRouter = createCubeRouter({ cubes: [employeesCube], drizzle: db, schema, extractSecurityContext: async (req) => ({ organisationId: req.user.orgId, userId: req.user.id })})
app.use('/', cubeRouter)Security Context Enforcement
Section titled “Security Context Enforcement”All MCP tools respect your security context:
drizzle_cube_loadexecutes queries with the security contextdrizzle_cube_discoveronly returns cubes the user has access to- Multi-tenant isolation is enforced on all data access
Enhancing AI Discovery
Section titled “Enhancing AI Discovery”The MCP tools work best when your cubes have rich semantic metadata. See Adding Semantic Metadata for how to add:
- Descriptions for cubes, measures, and dimensions
- Synonyms for alternate names (“revenue” → “sales”, “income”)
- Example questions that help AI understand the cube’s purpose
Try It Live
Section titled “Try It Live”Connect to the demo MCP server to try it out:
https://try.drizzle-cube.dev/mcpNext Steps
Section titled “Next Steps”- Adding Semantic Metadata - Make your cubes more discoverable
- Claude Desktop Setup - Connect Claude Desktop to your data
- Claude Code Plugin - Query from Claude Code