Think of store registration like setting up a new contact in your phone. You add their name (store identifier), their number (API endpoint), and maybe some notes about how to reach them (authentication details). Once saved, you can call them anytime without looking up the details again.
MCIP works the same way. Register a store once with its connection details, and every AI agent query automatically knows how to reach it. No repeated configuration, no manual routing—just seamless connectivity.
The simplest setup: one MCIP instance, one store. Perfect for getting started or dedicated deployments.
Environment Configuration:
# .env
# Store Identity
STORE_PROVIDER=VENDURE
STORE_ID=my-awesome-store
STORE_NAME="My Awesome Store"
# Connection Details
SOURCE_URL=https://api.mystore.com/shop-api
STOREFRONT_URL=https://mystore.com
# Authentication
SOURCE_API_KEY=your-api-key-here
# For GraphQL platforms
GRAPHQL_QUERY={products{items{id name slug description variants{id sku name price priceWithTax currencyCode stockLevel}featuredAsset{preview source}}}}Verification:
# Start MCIP
docker-compose up -d
# Trigger initial sync
curl -X POST http://localhost:8080/admin/sync \
-H "x-admin-api-key: your-admin-key"
# Verify products loaded
curl "http://localhost:8080/search?q=test"✅ Checkpoint: You should see products in the search response. If you see an empty array, check the sync logs.
For aggregating products across multiple platforms, MCIP supports configuration-based multi-store setup.
stores.yaml Configuration:
# config/stores.yaml
stores:
- id: electronics-hub
name: "Electronics Hub"
provider: SHOPIFY
enabled: true
priority: 1
connection:
url: https://electronics-hub.myshopify.com/admin/api/2024-01/products.json
auth:
type: bearer
token: ${ELECTRONICS_HUB_TOKEN}
options:
timeout: 5000
retries: 3
currency: USD
- id: fashion-outlet
name: "Fashion Outlet"
provider: WOOCOMMERCE
enabled: true
priority: 2
connection:
url: https://fashion-outlet.com/wp-json/wc/v3/products
auth:
type: basic
username: ${FASHION_OUTLET_KEY}
password: ${FASHION_OUTLET_SECRET}
options:
timeout: 8000
retries: 2
currency: EUR
- id: home-goods
name: "Home & Garden"
provider: VENDURE
enabled: true
priority: 3
connection:
url: https://homegoods.com/shop-api
graphqlQuery: ${VENDURE_QUERY}
options:
timeout: 5000
currency: USDEnvironment for Multi-Store:
# .env.production
# Store tokens (referenced in stores.yaml)
ELECTRONICS_HUB_TOKEN=shpat_xxxxxxxxxxxxx
FASHION_OUTLET_KEY=ck_xxxxxxxxxxxxx
FASHION_OUTLET_SECRET=cs_xxxxxxxxxxxxx
# Vendure query (minified)
VENDURE_QUERY={products{items{id name slug description variants{id sku price}featuredAsset{preview}}}}
# Config path
STORES_CONFIG_PATH=./config/stores.yamlMCIP loads configuration in layers, each overriding the previous:
This means you can set defaults in stores.yaml, override sensitive values via environment variables, and make temporary changes through the API—all without redeploying.
Here's the complete configuration schema with all available options:
interface StoreConfig {
// Identity
id: string; // Unique identifier (lowercase, no spaces)
name: string; // Human-readable display name
provider: string; // Adapter to use: VENDURE, SHOPIFY, etc.
enabled: boolean; // Whether to include in searches
// Priority & Behavior
priority: number; // Lower = higher priority (1 is highest)
weight: number; // Search result weighting (0.0 - 1.0)
// Connection
connection: {
url: string; // API endpoint URL
auth?: AuthConfig; // Authentication details
graphqlQuery?: string; // For GraphQL endpoints
headers?: Record<string, string>; // Custom headers
};
// Operational Settings
options: {
timeout: number; // Request timeout in ms (default: 5000)
retries: number; // Retry attempts on failure (default: 3)
retryDelay: number; // Delay between retries in ms (default: 1000)
currency: string; // Default currency code
rateLimit?: {
requests: number; // Max requests per window
window: number; // Window size in ms
};
};
// Health Check
healthCheck?: {
enabled: boolean; // Enable health monitoring
interval: number; // Check interval in ms (default: 60000)
endpoint?: string; // Custom health endpoint
timeout: number; // Health check timeout (default: 3000)
};
// Sync Settings
sync?: {
schedule?: string; // Cron expression for auto-sync
batchSize: number; // Products per batch (default: 100)
fullSyncInterval?: number; // Hours between full syncs
};
}MCIP validates all store configurations on startup:
# Check configuration without starting
npm run config:validate
# Output:
# ✓ Store 'electronics-hub' - Valid
# ✓ Store 'fashion-outlet' - Valid
# ✗ Store 'home-goods' - Invalid: missing required field 'connection.url'Never commit credentials to version control. This seems obvious, but let's make it foolproof:
# .gitignore
# Environment files
.env
.env.*
!.env.example
# Config with secrets
config/stores.yaml
!config/stores.example.yamlMCIP supports multiple authentication methods:
Bearer Token (Shopify, custom APIs):
auth:
type: bearer
token: ${STORE_API_TOKEN}
Basic Auth (WooCommerce, legacy systems):
auth:
type: basic
username: ${STORE_KEY}
password: ${STORE_SECRET}
API Key Header (various platforms):
auth:
type: header
headerName: X-API-Key
value: ${STORE_API_KEY}
OAuth2 (enterprise systems):
auth:
type: oauth2
clientId: ${OAUTH_CLIENT_ID}
clientSecret: ${OAUTH_CLIENT_SECRET}
tokenUrl: https://auth.platform.com/oauth/token
scopes:
- read_products
- read_inventory
When API keys need updating, MCIP supports zero-downtime rotation:
# Update credential in environment
export NEW_STORE_TOKEN=shpat_new_token_here
# Trigger config reload via API
curl -X POST http://localhost:8080/admin/reload-config \
-H "x-admin-api-key: your-admin-key" \
-H "Content-Type: application/json" \
-d '{"storeId": "electronics-hub", "credential": "NEW_STORE_TOKEN"}'
# Response:
# {"status": "success", "message": "Credentials updated for electronics-hub"}Imagine an AI agent trying to search a store that's been down for hours. Without health checks, every query fails slowly. With health checks, MCIP knows which stores are healthy and routes around problems automatically.
# In stores.yaml
healthCheck:
enabled: true
interval: 60000 # Check every minute
timeout: 3000 # 3 second timeout
endpoint: /health # Custom endpoint (optional)
failureThreshold: 3 # Mark unhealthy after 3 failures
successThreshold: 2 # Mark healthy after 2 successesCheck all stores:
curl http://localhost:8080/health/stores
Response:
{
"status": "degraded",
"stores": [
{
"id": "electronics-hub",
"name": "Electronics Hub",
"status": "healthy",
"lastCheck": "2025-01-15T10:30:00Z",
"latency": 245,
"uptime": "99.8%"
},
{
"id": "fashion-outlet",
"name": "Fashion Outlet",
"status": "unhealthy",
"lastCheck": "2025-01-15T10:30:00Z",
"error": "Connection timeout",
"failedChecks": 3
},
{
"id": "home-goods",
"name": "Home & Garden",
"status": "healthy",
"lastCheck": "2025-01-15T10:30:00Z",
"latency": 189,
"uptime": "100%"
}
]
}When a store becomes unhealthy, MCIP automatically:
// This happens automatically - no code needed!
// Unhealthy stores are filtered from the search pool
const healthyStores = stores.filter(s => s.status === 'healthy');
const results = await searchAcrossStores(healthyStores, query);Change store settings without restarting MCIP:
# Reload all store configurations
curl -X POST http://localhost:8080/admin/reload-config \
-H "x-admin-api-key: your-admin-key"
# Reload specific store
curl -X POST http://localhost:8080/admin/reload-config \
-H "x-admin-api-key: your-admin-key" \
-d '{"storeId": "electronics-hub"}'Temporarily remove a store from searches (useful during maintenance):
# Disable store
curl -X PATCH http://localhost:8080/admin/stores/fashion-outlet \
-H "x-admin-api-key: your-admin-key" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
# Re-enable store
curl -X PATCH http://localhost:8080/admin/stores/fashion-outlet \
-H "x-admin-api-key: your-admin-key" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'Need to prioritize a store during a promotion? Adjust on the fly:
curl -X PATCH [http://localhost:8080/admin/stores/fashion-outlet](http://localhost:8080/admin/stores/fashion-outlet) \
-H "x-admin-api-key: your-admin-key" \
-H "Content-Type: application/json" \
-d '{"priority": 1, "weight": 1.5}'| Task | Command |
|---|---|
| List all stores | GET /admin/stores |
| Check store health | GET /health/stores |
| Sync all products | POST /admin/sync |
| Sync one store | POST /admin/sync with {"storeId": "..."} |
| Disable store | PATCH /admin/stores/{id} with {"enabled": false} |
| Reload config | POST /admin/reload-config |
| Update credentials | POST /admin/reload-config with credential reference |
Your stores are registered and ready! Here's where to go from here: