Cin7 Core Analytics MCP Server

This server exposes Cin7 Core Analytics schema and semantics, validates PostgreSQL, and runs small read-only query results through the Model Context Protocol (MCP).

Approved MCP clients can discover the analytics warehouse, construct reporting queries, validate them against the physical PostgreSQL schema, preview up to five rows, and execute up to 100 rows after the client obtains explicit user approval. Query scope covers all Cin7 Core instances represented in this runtime namespace.

Analytics MCP readiness access

Sign in with an Analytics-authorized account to view readiness diagnostics. These connection instructions remain public.

MCP Endpoint: https://test-dear.growthpath.com.au/mcp-c7core-analytics
Public documentation: this HTML page does not require a Django login, so an MCP-capable assistant can read the connection instructions. The MCP endpoint itself always requires authentication.
Documentation URL vs MCP endpoint: /mcp_analytics_documentation/ is this human-readable page. Do not enter the documentation URL in an MCP client. Configure the client with https://test-dear.growthpath.com.au/mcp-c7core-analytics, which uses /mcp-c7core-analytics. An unauthenticated request to the MCP endpoint should return 401 with a WWW-Authenticate challenge.
Using the former /mcp_analytics/ URL? It is not the MCP transport. Browser requests redirect here, while MCP POST requests receive an incorrect_mcp_endpoint response. Use the exact endpoint https://test-dear.growthpath.com.au/mcp-c7core-analytics. The MCP transport starts OAuth with a 401 challenge.

Authentication and Connection

Preferred OAuth Setup

ChatGPT, Claude Desktop, Codex, and other clients that support MCP OAuth should be configured with the MCP server URL and allowed to complete the browser-based OAuth flow. The client discovers the authorization server from the endpoint's WWW-Authenticate response or the protected-resource metadata URL.

  • Server URL: https://test-dear.growthpath.com.au/mcp-c7core-analytics
  • Transport: streamable HTTP.
  • Protected-resource metadata path: /.well-known/oauth-protected-resource/mcp-c7core-analytics
  • Authorization server: https://test-dear.growthpath.com.au
  • OAuth flow: authorization code with PKCE S256 and dynamic public-client registration.
  • Requested scope: mcp_analytics.query

The person signing in must be an active Django user who is a superuser or belongs to the Django auth group named mcp-analytics. OAuth access and refresh tokens, authorization codes, and DRF token keys must remain in the client's approved credential store rather than chat messages, logs, or source control.

Default OAuth Scope Behavior

When a dynamic client registration request omits scope, the server registers the client as allowed to request both supported scopes:

  • mcp_analytics.query for this Analytics MCP resource.
  • mcp_dear.read for the separate Cin7 Core API MCP resource.

Registration does not grant both scopes to every access token. The authorization request must identify the intended MCP resource and request its matching scope. Tokens for https://test-dear.growthpath.com.au/mcp-c7core-analytics use mcp_analytics.query; mcp_dear.read cannot be used to access the Analytics endpoint.

Manual API Token Setup

Clients that cannot complete OAuth may use a Django REST Framework token belonging to an active MCP-authorized user. Send Authorization: Token <token key> on every request. A bare Authorization: <token key> value is also accepted for clients that cannot prepend the Token scheme. The token is not a Cin7 Core API key.

MCP Client Values

  • Server URL: https://test-dear.growthpath.com.au/mcp-c7core-analytics
  • Preferred authentication: OAuth with scope mcp_analytics.query.
  • Manual fallback header: Authorization: Token <token key>
  • OAuth status endpoint: /mcp_oauth/status/
  • Local client label: use a descriptive name such as cin7-core-analytics.

What This MCP Server Provides

The Analytics MCP server exposes 47 database tables from the Dear Analytics data warehouse, including:

Master Data Tables
  • dear_customer - Customer records with addresses and contacts
  • dear_product - Product catalog with pricing and availability
  • dear_supplier - Supplier information
  • dear_location - Warehouse locations
Transaction/Fact Tables
  • sales_fact - Revenue transactions with COGS analysis
  • purchases_fact - Purchase transactions
  • product_movements - Stock movements
  • sales_order_lines - Sales order line items

Choosing Between Analytics and Dear Operations

The Dear Operations MCP server is the cache-backed operational source. This Analytics MCP server may not be enabled in every deployment. When both are connected, choose the server from the question's required data shape and date semantics rather than treating either source as live Cin7 Core data.

Question shape Preferred server Reason
Historical revenue, COGS, margin, trends, rankings, custom grouping, or cross-table joins Analytics Supports custom read-only PostgreSQL over reporting tables.
Invoice or credit-note reporting using invoice dates Analytics sales_fact.transaction_date is the invoice date.
One order, purchase, product, customer, SKU, fulfilment, or nested document collection Dear Operations Provides targeted cache-backed document and collection tools.
Operational status queues, stuck orders, recent orders, or job diagnostics Dear Operations Provides cache searches, recent orders by SaleOrderDate, and job diagnostics.
Stock for one SKU, location, bin, or batch Dear Operations Provides targeted cached availability and movement tools.
Custom stock aggregation across products, locations, or other dimensions Analytics Supports custom aggregation and joins over analytics availability tables.
Simple supported aggregate when Analytics is unavailable Dear Operations Use its allowlisted aggregate reports or cache searches and disclose their limits.
Freshness-sensitive or apparently inconsistent result Inspect selectively Check timestamps and date semantics, then compare both sources only when needed.
Client compatibility: this server publishes the same routing policy through MCP initialize.instructions. MCP clients may choose whether to put those instructions in the model's context. The search_analytics_schema tool description also contains the essential routing hint.

Base and Reporting Currencies

Base-currency amounts can use different currencies across Dear instances. Tables with year_month_currency can join that column directly to avg_ex_rate. For other tables, join through dear_metadata, match base_currency_code with avg_ex_rate.from_currency, and match the value's calendar month with avg_ex_rate.value_date. Multiply each value by in_reporting_currency before aggregation. The common currency comes from DearPostgresAnalyticsSettings.reporting_currency and appears as avg_ex_rate.to_currency. Preserve monetary facts with a LEFT JOIN, report missing/null-rate counts, and do not present a complete converted total when coverage is incomplete or target currencies disagree. Synthetic quantity-only adjustments have no revenue amount and do not require revenue conversion. These exchange rates are single-date monthly approximations, sometimes carried forward, not calculated monthly averages.

sales_fact contains consolidated invoice/credit facts, separate CreditNoteRestock adjustments, and synthetic dropship rows; rows are not original invoice lines. Keep restocks when reporting margin. Stored invoice COGS is negative and restock COGS positive: add signed COGS to revenue for margin.

PostgreSQL rejects result rows exceeding the configured transport limit (64 KiB by default) before transferring their values to Django. Preview and execution accumulate results against a 256 KiB serialized-response budget. Truncated results are explicitly marked; narrow value searches before choosing among ambiguous filter literals.

Available Resources

Resource URI Description
analytics://tables List all 47 analytics tables with descriptions
analytics://schema/{table_name} Get detailed schema for a specific table (fields, types, foreign keys, indexes)
analytics://relationships Text diagram showing foreign key relationships between tables
analytics://database-info Database conventions, date handling, reporting currency, and namespace-wide Dear instance scope
analytics://query-policy Current PostgreSQL limits, allowed functions, and execution requirements
analytics://semantics Reviewed metrics, dimensions, synonyms, and default date fields
analytics://examples Topics containing reviewed PostgreSQL examples

Available Tools

Tool Purpose
search_analytics_schema Find tables and columns using physical schema metadata and reviewed business synonyms. Results use a strict structured MCP output schema.
search_analytics_examples Find reviewed PostgreSQL patterns with a strict structured MCP output schema.
lookup_analytics_valuesSearch approved filter dimensions.
validate_postgresql_queryParse and ground exact SQL without running it.
preview_postgresql_queryRun up to five rows and issue a short-lived token.
execute_postgresql_queryRun up to 100 rows after user approval.

Configuring Claude Code

Option 1: Project Configuration (Recommended for Teams)

Create a .mcp.json file in your project root:

{
  "mcpServers": {
    "analytics": {
      "type": "http",
      "url": "https://test-dear.growthpath.com.au/mcp-c7core-analytics"
    }
  }
}

This file can be committed to git so all team members share the same configuration.

The endpoint requires an MCP-authorized user. OAuth clients must request the mcp_analytics.query scope for the https://test-dear.growthpath.com.au/mcp-c7core-analytics resource.

Option 2: CLI Command

# Add the MCP server
claude mcp add --transport http analytics https://test-dear.growthpath.com.au/mcp-c7core-analytics

# Verify it's configured
claude mcp list

# Check connection status (within Claude Code)
/mcp

Scope Options

Scope Command Use Case
project claude mcp add --scope project ... Shared with team via .mcp.json in git
user claude mcp add --scope user ... Available across all your projects
local claude mcp add --scope local ... Private, current project only (default)

Practical Examples

Discovering Tables

Ask Claude to list available tables:

What analytics tables are available?

@analytics:analytics://tables

Understanding Table Structure

Get the schema for a specific table before writing queries:

Show me the structure of the sales_fact table.

@analytics:analytics://schema/sales_fact

Building JOIN Queries

Use the relationships resource to understand how tables connect:

How do I join sales data to customer information?

@analytics:analytics://relationships
@analytics:analytics://schema/sales_fact
@analytics:analytics://schema/dear_customer

Validating and Running a Query

Ask the MCP client to follow the staged workflow:

Find the top 10 customers by revenue for the last 12 months.
Search the schema and examples, validate the exact PostgreSQL query,
qualify every physical table with public, preview the query, show me the SQL
and preview, and wait for my approval before execution.

Exploring Product Data

I need to analyze product availability across locations.
What tables should I use and how do they relate?

@analytics:analytics://schema/dear_product
@analytics:analytics://schema/dear_product_availability
@analytics:analytics://schema/dear_location
@analytics:analytics://relationships

Deployment Notes

Kubernetes Deployment

The MCP server is integrated into Django's ASGI application and served at the /mcp-c7core-analytics path. No separate server or port is required.

The MCP endpoint is available at:

https://<your-ingress-hostname>/mcp-c7core-analytics

This integration means:

  • No additional Kubernetes deployment or service needed
  • MCP requests are handled by the same pods as the Django application
  • TLS is handled by ingress; the analytics MCP middleware validates DRF or OAuth credentials

Pre-authentication Proxy Trust

Rate limits use the original socket peer by default. Only configure MCP_ANALYTICS_TRUSTED_PROXY_CIDRS as a list or tuple of verified proxy networks whose proxies append the actual connecting address or replace incoming forwarding headers with a verified chain. Analytics does not inherit the Dear Operations proxy trust setting. For a trusted socket peer, all X-Forwarded-For fields are combined in received order and checked from right to left; the first untrusted address is used. Malformed configuration or chain entries discard the header, and a chain containing only trusted addresses retains the socket peer.

The ASGI server must preserve the original socket peer: disable upstream proxy-header rewriting before relying on this check. See the repository's mcp_dear/proxy_configuration.md for the shared ASGI serving contract, including the effect on forwarded scheme handling. Deployment configuration must be verified separately; this setting alone does not establish that the socket peer is preserved.

Local Development

For local development, you have two options:

Option A: Via Django (ASGI with Uvicorn)

# Start Django with ASGI server
uvicorn project.asgi:application --host 0.0.0.0 --port 8000

# MCP available at: http://localhost:8000/mcp-c7core-analytics

Option B: Standalone MCP Server

# Start dedicated MCP server on a different port
python manage.py mcp_server --port 8090

# MCP available at: http://localhost:8090/mcp-c7core-analytics

Available Tables

The following 47 tables are exposed via this MCP server:

Table Name Database Table Description
avg_ex_rate avg_ex_rate Monthly single-date exchange-rate approximations, normally using the fifteenth's rate rather than a monthly average. Early-current-month rates use an earlier date; unavailable months may carry forward the last available rate. value_date is a UTC month label, not the actual observation date.
dear_customer dear_customer dear customer table
dear_customer_addresses dear_customer_addresses Addresses associated with Customers
dear_customer_contacts dear_customer_contacts Contacts associated with Customers
dear_customer_tag dear_customer_tag Tags associated with Customers
dear_disassemblies_header dear_disassemblies_header Disassembly task header from Cin7 Core (Dear)
dear_disassemblies_order_lines dear_disassemblies_order_lines Inventory outputs from Dear disassembly orders
dear_disassemblies_order_service_lines dear_disassemblies_order_service_lines Service outputs from Dear disassembly orders
dear_disassemblies_pick_lines dear_disassemblies_pick_lines Source inventory picks from Dear disassembly tasks
dear_financial_transactions dear_financial_transactions Financial transactions from Cin7 Core (Dear). These are not auto updated.
dear_finished_goods_header dear_finished_goods_header Finished Goods assembly task header from Cin7 Core (Dear)
dear_finished_goods_order_lines dear_finished_goods_order_lines Component requirements from Finished Goods assembly orders
dear_finished_goods_pick_lines dear_finished_goods_pick_lines Actual component picks from Finished Goods assembly tasks
dear_location dear_location Dear Locations (that is, warehouses, not bins)
dear_metadata dear_metadata Dear Company Name: this table is useful if you have multiple Dear instances in the GrowthPath Analytics Connector
dear_po_header dear_po_header Purchase Order header
dear_product dear_product Product details from Cin7 Core (Dear)
dear_product_availability dear_product_availability Product availability from Dear, plus hard allocations (qty reserved for a specfic order)
dear_product_custom_prices dear_product_custom_prices Custom prices for products per customer.
dear_product_family dear_product_family Product Family details
dear_product_tag dear_product_tag Tags associated with Products
dear_sales_header sales_header Sales Header data
dear_sales_invoice sales_invoice Sales Invoices and Credit notes header: invoices and credit notes.
dear_stock_adjustment_header dear_stock_adjustment_header Stock Adjustment header
dear_stock_adjustment_lines dear_stock_adjustment_lines Stock Adjustment Lines
dear_stock_transfer_header dear_stock_transfer_header Stock Transfer
dear_stock_transfer_lines dear_stock_transfer_lines Stock Transfer Lines
dear_supplier dear_supplier Supplier details from Cin7 Core (Dear)
dear_supplier_product dear_supplier_product Products linked to Suppliers
mainfreight_events dear_zoho_analytics_mainfreight_events Mainfreight events
product_movements product_movements All stock movements with signed quantity, date, and base-currency value in amount
purchase_order_lines purchase_order_lines PO lines includng draft and not yet invoiced POs
purchase_order_payments purchase_order_payments Payments relating to POs, including deposits and invoice payments
purchases_fact purchases_fact based on authorised PO invoice lines
purchases_lines_lifecycle purchases_lines_lifecycle Shows the status of a PO line (what's been invoiced, received etc)
sales_fact sales_fact Consolidated authorised invoice and credit-note product facts, additional charges with synthetic product identifiers, separate CreditNoteRestock rows, and synthetic dropship quantity adjustments. This is not one row per original invoice line. Revenue is intended to reconcile to Xero/QBO and the Cin7 Core 'Sale Invoices & Credit Notes' report. Management margin uses actual COGS when available and average cost otherwise. Stored COGS is negative for invoices, positive for restocks, and zero for credit-note revenue rows; margin is revenue plus signed COGS. Synthetic dropship rows have no revenue or COGS amounts. Additional charges may not join to a product/SKU.
sales_lines_lifecycle sales_lines_lifecycle Shows the lifecycle status of lines on the sales order: quantity and value picked, shipped, invoiced etc
sales_order_inventory_transactions sales_order_inventory_transactions Inventory movements by date and value associated with the sales order, for detailed revenue and cogs analysis. Covers orders, shipments, credit notes and restocks
sales_order_lines sales_order_lines Sales order lines, including for draft orders and orders which are not yet invoiced
sales_order_payments sales_order_payments Payments and deposits (prepayments) known to Dear for sales orders
sales_shipments sales_shipments Information specifically about shipments, similar to the sales_order_inventory_transactions table, but only for shipments
shipping_subscriptions shipping_subscriptions OceanInsights Project44 data for containers on ships
table_update_status table_update_status During a data update with the Zoho connector, this table will show that a data update is in progress
threepl_stock_analysis threepl_stock_analysis Stores information about the stock levels of 3PLs. The table is unique by source_dear, stock_date, dear_location_od and product_guid
xero_account_transaction_lines xero_account_transaction_lines Xero journal lines synced from the Xero Journals API for selected account codes
xero_manual_journal_header xero_manual_journal_header Xero manual journal headers synced from the Xero Accounting API
xero_manual_journal_lines xero_manual_journal_lines Xero manual journal lines synced from the Xero Accounting API