EspoCRM GraphQL Server ๐
A high-performance, AI-optimized GraphQL server that dynamically generates schemas from EspoCRM metadata. Built specifically for modern AI agents and property management workflows.

๐ Features
๐ค AI Agent Optimized
- Dynamic Schema Generation - Automatically creates GraphQL schemas from EspoCRM metadata
- Intelligent Field Validation - Smart required field detection with error prediction
- Advanced Type Handling - Optimized array, enum, and multi-enum field processing
- Neural Query Optimization - AI-powered performance optimization and caching
- Predictive Error Recovery - Context-aware error handling with suggestions
- Optional EspoCRM - Server can start without EspoCRM configured for easier deployment
โก High Performance
- Multi-layer Caching - Redis + in-memory caching with intelligent invalidation
- Query Optimization - DataLoader integration preventing N+1 queries
- Real-time Sync - Auto-refreshing schema stays synchronized with EspoCRM
- Connection Pooling - Optimized database connections and API calls
- Performance Monitoring - Built-in metrics and bottleneck analysis
๐ข Real Estate & CRM Ready
- Property Management - Optimized for real estate workflows and data structures
- Multi-currency Support - International business operations with currency handling
- Compliance Features - GDPR and data protection compliance built-in
- Mobile-Optimized - Responsive queries for mobile applications
- Business Rule Engine - Automated validation for complex business workflows
๐ Enterprise Security
- Multi-auth Support - JWT, API keys, role-based access control
- Rate Limiting - Configurable rate limiting with IP whitelisting
- Data Protection - GDPR compliance with audit trails
- Security Headers - Comprehensive security middleware
- Vulnerability Scanning - Automated security scanning in CI/CD
๐ Table of Contents
๐ Quick Start
๐ฆ NPX Usage (Recommended)
The fastest way to get started:
npx espocrm-graphql-server
npx espocrm-mcp
npx espocrm-graphql-server init
npx espocrm-graphql-server --help
๐ฅ Installation
npm install -g espocrm-graphql-server
npx espocrm-graphql-server --version
๐ ๏ธ Development Setup
Prerequisites
- Node.js 20+ and npm/yarn
- EspoCRM instance with API access (optional - server can run without it)
- Redis (optional, for caching)
- Docker (for containerized deployment)
1. Clone and Install
git clone https://github.com/CG-Labs/EspoCRM-GraphQL-Server.git
cd EspoCRM-GraphQL-Server
npm install
2. Configure Environment
cp .env.example .env
3. Start Development Server
npm run dev
GraphQL Playground will be available at http://localhost:4000/graphql
๐ฆ Installation
Local Development
npm install
npm run setup:db
npm run schema:generate
npm run dev
Docker Development
docker-compose up -d
docker-compose logs -f graphql
docker-compose down
Production Docker
docker build -f Dockerfile.prod -t espocrm-graphql:latest .
docker-compose -f docker-compose.prod.yml up -d
โ๏ธ Configuration
Environment Variables
Create a .env
file based on .env.example
:
ESPOCRM_API_URL=https://your-espocrm.com/api/v1
ESPOCRM_API_KEY=your_api_key_here
ESPOCRM_USERNAME=admin
ESPOCRM_PASSWORD=your_password
MYSQL_HOST=your-mysql-host
MYSQL_PORT=3306
MYSQL_USER=espocrm_user
MYSQL_PASSWORD=your_mysql_password
MYSQL_DATABASE=espocrm_db
PORT=4000
NODE_ENV=production
LOG_LEVEL=info
JWT_SECRET=your-super-secret-jwt-key-here
API_RATE_LIMIT=100
API_RATE_WINDOW=15
REDIS_URL=redis://localhost:6379
CACHE_TTL=300
AI_OPTIMIZATION_ENABLED=true
PERFORMANCE_MONITORING=true
AUTO_SCHEMA_REFRESH=true
SCHEMA_REFRESH_INTERVAL=3600
ORGANIZATION_NAME=Your Organization
DEFAULT_CURRENCY=GBP
PROPERTY_MANAGEMENT_MODE=true
COMPLIANCE_MODE=GDPR_UK
ENABLE_METRICS=true
METRICS_PORT=9090
ENABLE_TRACING=false
JAEGER_ENDPOINT=http://localhost:14268/api/traces
GRAPHQL_PLAYGROUND=true
GRAPHQL_INTROSPECTION=true
DEBUG_MODE=false
Advanced Configuration
For advanced configuration, edit config/default.json
:
{
"server": {
"port": 4000,
"cors": {
"origin": ["http://localhost:3000", "https://yourdomain.com"],
"credentials": true
}
},
"espocrm": {
"apiUrl": "https://your-espocrm.com/api/v1",
"timeout": 30000,
"retries": 3,
"rateLimit": {
"requests": 100,
"window": 60000
}
},
"cache": {
"type": "redis",
"ttl": 300,
"prefix": "espocrm:graphql:"
},
"ai": {
"optimizationEnabled": true,
"learningEnabled": true,
"performancePrediction": true
}
}
๐ Security
Authentication
The GraphQL server supports multiple authentication methods to protect your data:
API Key Authentication
Configure API key authentication by setting the following environment variables:
GRAPHQL_REQUIRE_AUTH=true
GRAPHQL_API_KEYS=key1,key2,key3 # Comma-separated list
GRAPHQL_MASTER_KEY=master-key-for-admin
Include the API key in your requests:
curl -X POST https://your-server/graphql \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{"query": "{ contacts { edges { node { id } } } }"}'
curl -X POST https://your-server/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{"query": "{ contacts { edges { node { id } } } }"}'
Security Features
Rate Limiting
Prevents abuse by limiting the number of requests:
RATE_LIMIT_MAX_REQUESTS=30 # Max requests per window
RATE_LIMIT_WINDOW_MS=60000 # Time window (1 minute)
Query Depth Limiting
Prevents malicious deeply nested queries:
GRAPHQL_DEPTH_LIMIT=10 # Maximum query depth
GRAPHQL_COMPLEXITY_LIMIT=1000 # Maximum complexity score
CORS Configuration
Control which origins can access your API:
CORS_ORIGIN=https://your-frontend.com # Specific origin
# or
CORS_ORIGIN=* # Allow all (not recommended for production)
Production Security Checklist
- โ
Enable HTTPS - Always use SSL/TLS in production
- โ
Set NODE_ENV=production - Enables production optimizations
- โ
Enable Authentication - Set
GRAPHQL_REQUIRE_AUTH=true
- โ
Use Strong API Keys - Minimum 32 characters, randomly generated
- โ
Configure CORS - Restrict to your specific frontend domain
- โ
Set Rate Limits - Adjust based on your usage patterns
- โ
Disable Introspection - Set
ENABLE_INTROSPECTION=false
- โ
Hide Error Details - Production mode sanitizes error messages
- โ
Regular Updates - Keep dependencies and Node.js updated
- โ
Monitor Access Logs - Track and audit API usage
The server includes Helmet.js for security headers:
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- X-XSS-Protection: 1; mode=block
- Strict-Transport-Security (when using HTTPS)
- Content-Security-Policy (configurable)
Endpoint Security
/graphql | Optional/Required | Yes | Main GraphQL API |
/health | None | No | Health check |
/schema-info | Optional | Yes | Schema information |
/refresh-schema | Required | Strict | Manual schema refresh |
๐ณ Coolify Deployment
Step 1: Prepare Your Coolify Server
- Install Coolify on your server following the official documentation
- Access Coolify dashboard at
https://your-server.com:8000
Step 2: Create New Application
-
Create Project:
- Go to "Projects" โ "Create New Project"
- Name:
EspoCRM GraphQL Server
- Description:
AI-optimized GraphQL server for EspoCRM
-
Add Application:
- Click "Create Application"
- Choose "Dockerfile" deployment (NOT Docker Compose)
- Repository:
https://github.com/CG-Labs/EspoCRM-GraphQL-Server.git
- Branch:
main
- Dockerfile Location:
./Dockerfile.coolify
Step 3: Configure Environment Variables
In Coolify dashboard, add these minimum required environment variables:
NODE_ENV=production
PORT=4000
LOG_LEVEL=info
ESPOCRM_URL=https://your-espocrm.example.com
ESPOCRM_API_KEY=your_api_key_here
MYSQL_HOST=your_mysql_host
MYSQL_USER=espocrm_user
MYSQL_PASSWORD=your_secure_password
MYSQL_DATABASE=espocrm_db
JWT_SECRET=generate_a_secure_random_string_here
API_RATE_LIMIT=100
REDIS_URL=redis://redis:6379
AI_OPTIMIZATION_ENABLED=true
PERFORMANCE_MONITORING=true
AUTO_SCHEMA_REFRESH=true
ORGANIZATION_NAME=Your Organization
DEFAULT_CURRENCY=GBP
PROPERTY_MANAGEMENT_MODE=true
COMPLIANCE_MODE=GDPR_UK
Important Notes:
- The server can start without EspoCRM configured
- Use
ESPOCRM_URL
(not ESPOCRM_API_URL
) for the base URL
- The API path
/api/v1
is added automatically
- Health checks will pass even without EspoCRM
Step 4: Configure Docker Compose
Coolify will use the docker-compose.prod.yml
file:
version: '3.8'
services:
graphql:
image: node:18-alpine
working_dir: /app
command: sh -c "npm ci --only=production && npm start"
ports:
- "4000:4000"
environment:
- NODE_ENV=production
volumes:
- .:/app
depends_on:
- redis
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:4000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
volumes:
redis_data:
Step 5: Deploy
Step 6: Production Optimizations
Configure Monitoring
ENABLE_METRICS=true
METRICS_PORT=9090
PROMETHEUS_ENDPOINT=/metrics
Setup Backups
BACKUP_ENABLED=true
BACKUP_SCHEDULE=0 2 * * *
BACKUP_RETENTION=7
Configure Scaling
COOLIFY_SCALE_MIN=1
COOLIFY_SCALE_MAX=5
COOLIFY_CPU_LIMIT=1000m
COOLIFY_MEMORY_LIMIT=2Gi
Coolify Health Checks
The application includes comprehensive health checks:
GET /health
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00.000Z",
"uptime": 3600,
"version": "1.0.0",
"services": {
"espocrm": "connected",
"redis": "connected",
"database": "connected"
},
"performance": {
"memoryUsage": "125MB",
"cpuUsage": "15%",
"responseTime": "45ms"
}
}
Troubleshooting Coolify Deployment
Common Issues:
-
Environment Variables Not Loading:
docker-compose logs graphql | grep ENV
-
Redis Connection Issues:
docker-compose ps redis
docker-compose exec redis redis-cli ping
-
EspoCRM API Connection:
curl -H "X-Api-Key: $ESPOCRM_API_KEY" $ESPOCRM_API_URL/App/user
-
Memory Issues:
COOLIFY_MEMORY_LIMIT=4Gi
๐๏ธ Development
Project Structure
espocrm-graphql/
โโโ src/
โ โโโ core/ # Core GraphQL logic
โ โ โโโ SchemaManager.js # Dynamic schema generation
โ โ โโโ TypeGenerator.js # GraphQL type creation
โ โ โโโ ResolverGenerator.js # Resolver generation
โ โ โโโ AIOptimizer.js # AI-powered optimizations
โ โโโ clients/ # External service clients
โ โ โโโ EspoCRMClient.js # EspoCRM API client
โ โโโ services/ # Business logic services
โ โโโ middleware/ # Express middleware
โ โโโ cache/ # Caching layer
โ โโโ utils/ # Utility functions
โโโ tests/ # Test suites
โโโ config/ # Configuration files
โโโ docs/ # Documentation
โโโ scripts/ # Deployment scripts
Development Commands
npm run dev
npm run type-check
npm run lint
npm run lint:fix
npm run test
npm run test:unit
npm run test:integration
npm run test:e2e
npm run test:coverage
npm run schema:generate
npm run schema:validate
npm run schema:introspect
npm run test:performance
npm run test:load
npm run build
npm run start
npm run docker:build
npm run docker:run
Adding New Features
๐ API Documentation
GraphQL Schema
The server dynamically generates GraphQL schemas based on your EspoCRM metadata. Here are some example queries:
Query Examples
query GetContacts($first: Int, $after: String) {
contacts(first: $first, after: $after) {
edges {
node {
id
name
emailAddress
phoneNumber
account {
name
website
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
query GetProperties($filter: PropertyFilter) {
properties(filter: $filter) {
edges {
node {
id
address
propertyType
rentAmount
currency
tenancies {
edges {
node {
id
status
startDate
endDate
tenant {
name
emailAddress
}
}
}
}
}
}
}
}
query GetDashboardData {
properties(first: 10) {
totalCount
edges {
node {
id
address
status
}
}
}
activeTenancies: tenancies(filter: { status: ACTIVE }) {
totalCount
}
maintenanceRequests(filter: { status: OPEN }) {
totalCount
edges {
node {
id
priority
description
property {
address
}
}
}
}
}
Mutation Examples
mutation CreateProperty($input: PropertyInput!) {
createProperty(input: $input) {
id
address
propertyType
rentAmount
currency
status
}
}
mutation UpdateTenancy($id: ID!, $input: TenancyUpdateInput!) {
updateTenancy(id: $id, input: $input) {
id
status
startDate
endDate
rentAmount
}
}
mutation CreateMaintenanceRequests($inputs: [MaintenanceRequestInput!]!) {
createMaintenanceRequests(inputs: $inputs) {
id
priority
description
status
property {
address
}
}
}
Subscription Examples
subscription PropertyUpdates($propertyId: ID!) {
propertyUpdated(id: $propertyId) {
id
status
lastUpdated
tenancy {
status
tenant {
name
}
}
}
}
subscription MaintenanceAlerts {
maintenanceRequestCreated {
id
priority
description
property {
address
}
}
}
Authentication
JWT Authentication
const response = await fetch('/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: 'user@example.com',
password: 'password'
})
});
const { token } = await response.json();
const graphqlResponse = await fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
query: `query { contacts { edges { node { name } } } }`
})
});
API Key Authentication
const response = await fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your-api-key-here'
},
body: JSON.stringify({
query: `query { properties { totalCount } }`
})
});
โก Performance Optimization
Caching Strategy
The server implements multi-layer caching:
- Schema Cache (30 minutes TTL)
- Query Result Cache (5 minutes TTL)
- Metadata Cache (1 hour TTL)
- DataLoader Cache (per-request)
Query Optimization
Use DataLoader for Related Data
const contacts = await getContacts();
for (const contact of contacts) {
const account = await getAccount(contact.accountId);
}
const contacts = await getContactsWithAccounts();
query GetLargeDataset($first: Int = 50, $after: String) {
properties(first: $first, after: $after) {
edges {
cursor
node {
id
address
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Performance Monitoring
Access performance metrics at /metrics
:
# GraphQL query performance
graphql_query_duration_seconds{operation="GetContacts"} 0.045
graphql_query_count{operation="GetContacts",status="success"} 1523
# Cache performance
cache_hit_rate{cache="schema"} 0.95
cache_miss_count{cache="query"} 145
# EspoCRM API performance
espocrm_api_duration_seconds{endpoint="/Contact"} 0.120
espocrm_api_error_count{endpoint="/Contact"} 3
๐ค MCP Integration
The server includes built-in support for the Model Context Protocol (MCP), allowing AI assistants like Claude to directly interact with your CRM data.
What is MCP?
MCP (Model Context Protocol) is an open protocol that enables AI assistants to connect with external data sources and tools in a secure, standardized way.
Quick Setup
Local MCP Server (Claude Desktop)
-
Configure Claude Desktop:
Edit your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"espocrm": {
"command": "node",
"args": ["/path/to/espocrm-graphql-server/dist/mcp/index.js"],
"env": {
"MCP_GRAPHQL_ENDPOINT": "http://localhost:4000/graphql",
"MCP_API_KEY": "your-api-key"
}
}
}
}
-
Restart Claude Desktop to load the MCP server.
Remote MCP Server (Cloudflare Workers)
Deploy as an internet-accessible MCP server:
npm create cloudflare@latest espocrm-mcp --template=cloudflare/ai/demos/remote-mcp-authless
wrangler deploy
Available MCP Tools
- query_contacts - Search and retrieve contacts
- query_accounts - Search company information
- query_leads - Retrieve sales leads
- create_contact - Create new contacts
- execute_graphql - Run custom GraphQL queries
Use Cases
- Customer Support - Quick customer lookups during support
- Sales Intelligence - Query leads and opportunities
- Data Analysis - Complex queries through natural language
- Automation - Bulk operations via AI commands
For complete MCP documentation, see docs/MCP_INTEGRATION.md.
๐งช Testing
Running Tests
npm test
npm run test:unit
npm run test:integration
npm run test:e2e
npm run test:performance
npm run test:coverage
npm run test:watch
Test Structure
tests/
โโโ unit/ # Unit tests
โ โโโ core/ # Core component tests
โ โโโ services/ # Service tests
โ โโโ utils/ # Utility tests
โโโ integration/ # Integration tests
โ โโโ espocrm/ # EspoCRM API tests
โ โโโ graphql/ # GraphQL API tests
โโโ e2e/ # End-to-end tests
โโโ performance/ # Performance benchmarks
โโโ load/ # Load testing
โโโ fixtures/ # Test data
Writing Tests
Unit Test Example
import { SchemaManager } from '../../../src/core/SchemaManager.js';
describe('SchemaManager', () => {
let schemaManager;
beforeEach(() => {
schemaManager = new SchemaManager({
espocrm: { apiUrl: 'http://test.com' }
});
});
test('should generate schema from metadata', async () => {
const metadata = { entities: ['Contact', 'Account'] };
const schema = await schemaManager.generateSchema(metadata);
expect(schema).toBeDefined();
expect(schema.getType('Contact')).toBeDefined();
expect(schema.getType('Account')).toBeDefined();
});
});
Integration Test Example
import { createTestServer } from '../../utils/testServer.js';
describe('GraphQL Queries', () => {
let server;
beforeAll(async () => {
server = await createTestServer();
});
test('should fetch contacts with pagination', async () => {
const query = `
query {
contacts(first: 10) {
edges {
node {
id
name
}
}
pageInfo {
hasNextPage
}
}
}
`;
const response = await server.executeOperation({ query });
expect(response.errors).toBeUndefined();
expect(response.data.contacts.edges).toHaveLength(10);
});
});
Performance Testing
npm run test:performance
npm run test:load
artillery run tests/load/artillery.config.yml
๐ Monitoring
Health Checks
The server provides comprehensive health checks:
curl http://localhost:4000/health
curl http://localhost:4000/health/detailed
curl http://localhost:4000/ready
curl http://localhost:4000/live
Metrics and Observability
Prometheus Metrics
Access metrics at http://localhost:4000/metrics
:
- HTTP Request Metrics: Duration, status codes, request counts
- GraphQL Metrics: Query performance, error rates, complexity scores
- EspoCRM API Metrics: Response times, error rates, rate limiting
- Cache Metrics: Hit rates, miss counts, evictions
- System Metrics: Memory usage, CPU utilization, uptime
Grafana Dashboard
A pre-configured Grafana dashboard is available in monitoring/grafana/
:
- GraphQL Performance: Query response times, throughput, error rates
- EspoCRM Integration: API response times, success rates, quota usage
- System Health: Memory, CPU, disk usage, network I/O
- Business Metrics: Property queries, tenant searches, maintenance requests
Logging
Structured logging with Winston:
logger.info('Schema generated successfully', {
entities: metadata.entities.length,
duration: Date.now() - startTime,
version: schemaVersion
});
logger.error('EspoCRM API error', {
endpoint: '/Contact',
statusCode: 500,
error: error.message,
requestId: req.id
});
๐ค Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Workflow
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Make your changes with proper tests
- Run the test suite:
npm test
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
Code Style
- Use TypeScript for new code
- Follow ESLint configuration
- Write comprehensive tests
- Document public APIs
- Follow conventional commits
Pull Request Process
- Ensure all tests pass
- Update documentation if needed
- Add entry to CHANGELOG.md
- Request review from maintainers
- Address review feedback
- Squash commits before merge
๐ Support
Getting Help
- Documentation: Check this README and
/docs
folder
- GitHub Issues: Report bugs and request features
- Discussions: Community support and questions
- Email: support@example.com
Common Issues
Schema Not Updating
curl -X POST http://localhost:4000/admin/refresh-schema
curl http://localhost:4000/admin/cache-stats
Performance Issues
curl http://localhost:4000/metrics
export LOG_LEVEL=debug
npm restart
EspoCRM Connection Problems
curl -H "X-Api-Key: $ESPOCRM_API_KEY" $ESPOCRM_API_URL/App/user
curl -H "X-Api-Key: $ESPOCRM_API_KEY" $ESPOCRM_API_URL/App/user/acl
Troubleshooting Guide
See our detailed Troubleshooting Guide for common issues and solutions.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Apollo GraphQL for the excellent GraphQL server
- EspoCRM for the flexible CRM platform
- Our amazing community of contributors
Built with โค๏ธ for the open source community
For more information, visit the GitHub repository.