Juniper Commerce Docs
Everything you need to understand the onX standard, build your adapter, integrate with UCP, and validate conformance.
Getting Started
The onX (Order Network eXchange) standard defines a common MCP (Model Context Protocol) interface for commerce fulfillment operations. Any AI platform can connect to any onX-compliant adapter using a single, consistent protocol.
Juniper Commerce is the reference app maintained by the Commerce Operations Foundation . Source: juniper-commerce on GitHub .
Path A — Docker (recommended)
From the repository root, run the interactive setup wizard. It writes a .env file, chooses Demo vs Full Install, data store (PostgreSQL or SQLite when not in Demo), optional AI keys, and optional MCP server profile. When it finishes, use the docker compose command it prints (it may add --profile flags for Postgres and/or the MCP server).
npm run setup docker compose up --build # → http://localhost:3000 (adjust if PORT in .env differs)
Path B — Local development
Run the Next.js app directly for fast iteration. Copy the example env file, adjust APP_MODE, DATA_MODE, and keys as needed (defaults favor Demo + in-memory).
npm install cp .env.example .env.local npm run dev # → http://localhost:3000
Conformance
With the app running, open the built-in runner to execute the full suite against your instance.
DataProvider with per-session isolation and TTL so visitors don't share data. Install (Full) mode turns on persistent storage: configure DATA_MODE=postgres or sqlite and the matching DATABASE_URL. In Install mode, when you include the MCP reference server in setup, it runs alongside Juniper via Docker Compose; Juniper calls it using ONX_MCP_SERVER_URL.Architecture
Juniper v2 is a Next.js application that exposes REST and UCP endpoints, maps them to the same twelve onX operations, and powers the Playground with pluggable AI and data backends. The onX contract itself is implemented by adapters behind the MCP reference server; Juniper can call that server over HTTP in full install setups or fulfill operations through its own DataProvider abstraction.
- DataProvider — Swappable persistence:
memory(session-scoped stores),postgres, orsqlite, selected viaDATA_MODEand environment. - LLM provider — Unified interface with concrete drivers for Anthropic, OpenAI, Google Gemini, and Ollama. The app picks a provider from which API keys or Ollama URL are set.
- Two-mode architecture — Demo (
APP_MODE=demo): in-memory data, rate limits, no admin settings UI. Install / Full (APP_MODE=full): persistent data, full Playground, settings, and optional MCP server integration.
The 12 Operations
Adapters implement IFulfillmentAdapter and expose these MCP tools.
get-productsList product catalogget-product-variantsList SKUs & optionsget-inventoryStock levels by SKU/locationget-customersCustomer lookupget-ordersOrder history & filteringcreate-sales-orderPlace a new orderupdate-orderModify an existing ordercancel-orderCancel with reasonfulfill-orderShip with trackingget-fulfillmentsFulfillment statuscreate-returnInitiate return/RMAget-returnsReturn historyStack overview
┌──────────────────────────────────────────────────────────────────────┐
│ Juniper Commerce (Next.js) │
│ • Routes: storefront, REST APIs, UCP bridge, Playground, conformance│
│ • Demo mode: in-memory DataProvider, isolated per browser session │
│ • Full / Install: Postgres or SQLite + settings + optional MCP URL │
├──────────────────────────────────────────────────────────────────────┤
│ LLM layer (one active provider from env) │
│ Anthropic (Claude) │ OpenAI │ Google Gemini │ Ollama (local) │
├──────────────────────────────────────────────────────────────────────┤
│ Commerce logic → 12 onX operations (tools / API handlers) │
│ DataProvider: Memory │ PostgreSQL │ SQLite │
└──────────────────────────────────────────────────────────────────────┘
│ ONX_MCP_SERVER_URL (optional, typical in Docker Compose)
▼
┌──────────────────────────────────────────────────────────────────────┐
│ MCP reference server (HTTP) — mock or custom IFulfillmentAdapter │
│ Protocol: MCP tools map to the same 12 operations │
└──────────────────────────────────────────────────────────────────────┘src/lib (data providers, LLM factory, onx-client.ts). In Demo mode, requests stay inside the app process; in Full Install with MCP enabled, Juniper delegates to the reference server defined by ONX_MCP_SERVER_URL.Build Your Adapter
An adapter wraps your fulfillment system (Shopify, NetSuite, custom WMS, etc.) and implements the onX interface. Use the template from adapter-template/ in the Commerce Operations Foundation repositories as your starting point.
Step 1: Scaffold
cp -r adapter-template my-adapter cd my-adapter npm install # Edit src/adapter.ts
Step 2: Implement the interface
import type { IFulfillmentAdapter } from '@cof-org/mcp';
export class MyAdapter implements IFulfillmentAdapter {
async getOrders(params) {
// Fetch from your system
const orders = await myAPI.listOrders(params);
// Return in onX format
return { items: orders.map(toOnXOrder), total: orders.length };
}
async createSalesOrder(input) {
const order = await myAPI.createOrder(input);
return toOnXOrder(order);
}
// ... implement all 12 operations
}Step 3: Configure and test
# Point the MCP server at your built adapter (see server docs for env vars) ADAPTER_TYPE=local ADAPTER_PATH=./dist/adapter.js node server/dist/index.js # With Juniper running, validate the HTTP surface from the web UI: # http://localhost:3000/conformance
Step 4: Publish to npm
npm publish --access public # Consumers can then use: # ADAPTER_TYPE=npm ADAPTER_PACKAGE=@myco/onx-adapter
schemas/. The conformance runner in Juniper validates your deployment against these expectations from the UI.UCP Integration
The Universal Commerce Protocol (UCP) lets AI platforms discover and consume your commerce capabilities via a standardized manifest. This app implements the full UCP bridge.
Discovery Manifest
Expose your capabilities at /.well-known/ucp:
{
"version": "1.0",
"name": "My Store",
"baseUrl": "https://store.example.com",
"capabilities": [
{
"id": "dev.ucp.shopping.catalog",
"type": "catalog",
"endpoint": "/api/ucp/catalog",
"methods": ["GET", "POST"]
},
{
"id": "dev.ucp.shopping.checkout",
"type": "checkout",
"endpoint": "/api/ucp/checkout",
"methods": ["POST"]
}
],
"auth": {
"type": "apiKey",
"apiKeyHeader": "Authorization"
}
}Request/Response Flow
AI Platform → POST /.well-known/ucp discovery
AI Platform → GET /api/ucp/catalog?query=jacket
AI Platform → POST /api/ucp/checkout { items, customer, address }
→ translates to onX create-sales-order
→ returns { orderId, status, total }
AI Platform → GET /api/ucp/fulfillment?orderId=X
→ translates to onX get-fulfillments
→ returns { orderId, status, trackingNumbers }Conformance Testing
The conformance runner validates that your Juniper (or proxied onX) HTTP surface meets the reference expectations. Run it from the web UI—no separate CLI package required.
Web UI
Open /conformance while the app is running. Start a run to execute all suites against the configured base URL (typically this app on localhost).