MCP Server Overview
The AEX MCP server (@aex/mcp-server) exposes the AEX market engine as a set of tools consumable by Claude Code and other Model Context Protocol clients. With 43 tools across four categories, you can query live market state, submit and cancel orders, monitor real-time event streams, and drive AI-powered market simulations — all from within a Claude Code session.
By default, the server communicates via stdio transport. Set MCP_HTTP_PORT to enable Streamable HTTP transport for remote deployment. In both modes, the server connects to your AEX backend over HTTP (for entity/user queries) and native WebSocket (for real-time market data, mutations, and event streaming).
Prerequisites
- Node.js 18+ installed
- A running AEX backend — the server connects to it at startup
- The following environment variables configured (see below)
Environment Variables
The server reads configuration from environment variables. Set DOTENV_PATH to load a .env file at startup (local development only; containers inject env vars at runtime).
| Variable | Required | Description |
|---|---|---|
AEX_HOST | Yes | AEX backend hostname and port (e.g. localhost:8080 or api.dev.aem.aotearoa.energy) |
AEX_USER_ID | Yes | Azure AD Object ID of the user to act as. Must be a registered AEX user. |
AEX_BASE_URL | No | AEX backend base URL for HTTP client (defaults to http://localhost:3001) |
AEX_BEARER_TOKEN | No | Bearer token for authenticated API calls (production environments) |
STRESS_TEST_SECRET | No | Enables stress/dev-only tools such as aex_dev_reset_credit_and_docs |
STORAGE_TABLE_ENDPOINT | No | Azure Table Storage endpoint (required for audit log and order events tools) |
STORAGE_ACCOUNT_NAME | No | Azure Storage account name |
AEX_STORAGE_KEY | No | Azure Storage account key (local dev only; production uses DefaultAzureCredential) |
DOTENV_PATH | No | Path to a .env file to load at startup (local development only). |
MCP_HTTP_PORT | No | Port to listen on for Streamable HTTP transport. When set, HTTP mode is activated instead of stdio. |
MCP_BEARER_TOKEN | No | Bearer token required on /mcp requests in HTTP mode. Omit to disable auth (not recommended for production). |
AEX_USER_ID must be the Azure AD Object ID of a user already registered in AEX. Mutations are executed as this user, so the user must belong to the correct entity and hold the appropriate permissions. Use aex_list_users to discover registered users.
Connection Model
The MCP server maintains two independent connections to AEX:
HTTP (state client) — used for entity and user query tools. Fetches live data from AEX admin REST endpoints (GET /api/admin/entities, GET /api/admin/users). Available immediately on startup, no explicit connection step required.
WebSocket (PubSub client) — used for mutation tools, real-time event monitoring, and market data queries. You must call aex_connect_pubsub before using any mutation tool or querying orders, fills, products, contracts, or credit. Once connected, the server populates an in-memory snapshot cache from the statePath messages AEX sends on connect, and receives a live stream of market events into an in-memory event buffer.
Transport modes
The server supports two transport modes that determine how MCP clients connect to it.
stdio (default — local Claude Code)
Claude Code launches the server as a child process and communicates over stdin/stdout. This is the default when MCP_HTTP_PORT is not set.
┌─────────────────────────────────────────┐
│ Claude Code / MCP client │
└────────────────┬────────────────────────┘
│ stdio
┌────────────────▼────────────────────────┐
│ aex-mcp server │
│ │
│ ┌─────────────────┐ ┌──────────────┐ │
│ │ State client │ │ PubSub client│ │
│ │ (HTTP/REST) │ │ (WebSocket) │ │
│ └────────┬────────┘ └──────┬───────┘ │
└───────────┼──────────────────┼──────────┘
│ │
┌──────▼──────────────────▼──────┐
│ AEX backend │
│ (Express + ws) │
└────────────────────────────────┘
HTTP (remote — Azure Container App)
Set MCP_HTTP_PORT to activate Streamable HTTP transport. The server listens on that port and handles MCP requests over HTTPS, making it suitable for remote or multi-user deployments (e.g. as an Azure Container App). This transport is stateless: each POST /mcp request creates a fresh server and transport instance — no session state is held between requests.
┌──────────────────────────────────────────────┐
│ Remote MCP client │
│ (Claude Code, web app, etc.) │
└─────────────────────┬────────────────────────┘
│ HTTPS POST /mcp
│ Authorization: Bearer <token>
┌─────────────────────▼────────────────────────┐
│ aex-mcp server (HTTP) │
│ │
│ GET /health ── liveness probe (no auth) │
│ POST /mcp ── MCP Streamable HTTP │
│ (stateless per-request) │
│ │
│ ┌─────────────────┐ ┌──────────────┐ │
│ │ State client │ │ PubSub client│ │
│ │ (HTTP/REST) │ │ (WebSocket) │ │
│ └────────┬────────┘ └──────┬───────┘ │
└───────────┼──────────────────┼───────────────┘
│ │
┌──────▼──────────────────▼──────┐
│ AEX backend │
│ (Express + ws) │
└────────────────────────────────┘
| Endpoint | Auth | Purpose |
|---|---|---|
GET /health | None | Liveness probe — returns { "status": "ok" } |
POST /mcp | Bearer token (if MCP_BEARER_TOKEN is set) | MCP Streamable HTTP transport |
Tool Categories
The server exposes 43 tools split into four categories:
Query tools (22 tools)
Read-only tools. Entity, user, and audit log tools query AEX via HTTP and are safe to call at any time without a WebSocket connection. Market data tools (orders, fills, products, contracts, order book, market state, credit) read from the in-memory snapshot cache and require aex_connect_pubsub to be called first.
Mutation tools (11 tools)
Write operations that send requests to AEX over WebSocket and wait for confirmation. Require aex_connect_pubsub to be called first. Includes order submission and cancellation, market halt/resume, credit limit management, and testing utilities.
Monitor tools (5 tools)
Read events from the in-memory event buffer populated by the WebSocket connection. Return buffered events with sequence numbers for efficient polling. Includes aex_get_recent_events and per-category watch tools.
Simulation tools (5 tools)
Control the aex-sim AI market simulator. Start and stop simulations with configurable trading personas, trigger synthetic market events, and query the spot price model.
Quick Start
The typical workflow is:
1. Verify connectivity
aex_ping
aex_connection_status
2. Query entities and users (no connection required)
aex_list_entities
aex_list_users
These tools use the HTTP client and are available immediately.
3. Connect for market data and real-time operations
aex_connect_pubsub
Pass a userId to connect as a specific user, or omit to use AEX_USER_ID from the environment. Once connected, the snapshot cache is populated and all market data tools become available.
4. Explore market state and submit orders
aex_get_market_state
aex_list_products
aex_get_order_book
aex_create_test_order { contractId, side, price, quantity }
aex_watch_orders
aex_list_orders { status: "working" }
5. Clean up
aex_cancel_order { orderId }
aex_disconnect_pubsub
Use aex_get_module_schema and aex_find_modules for flexible ad-hoc queries across any module type. These tools support operators like gt, lt, contains, and in for precise filtering.
HTTP Mode Quick Start
HTTP mode is used for remote deployments — the server runs as a container and MCP clients connect over HTTPS instead of stdio.
Running locally
# Start the server in HTTP mode on port 4087 (no auth)
MCP_HTTP_PORT=4087 node dist/index.js
# With bearer token auth (recommended for any non-local use)
MCP_HTTP_PORT=4087 MCP_BEARER_TOKEN=mysecret node dist/index.js
Environment variables (HTTP mode)
| Variable | Required | Description |
|---|---|---|
MCP_HTTP_PORT | Yes | Port for the HTTP server (containers default to 4087) |
MCP_BEARER_TOKEN | Recommended | Token callers must supply as Authorization: Bearer <token> on /mcp requests. Omit to disable auth (local dev only). |
MAX_BODY_SIZE | No | Maximum accepted request body size in bytes (default: 1 MiB). Requests exceeding this limit are rejected with HTTP 413 Payload Too Large. |
All AEX connection variables (AEX_HOST, AEX_BASE_URL, AEX_WS_URL, AEX_USER_ID, AEX_BEARER_TOKEN) are the same in both modes.
Verifying the server is up
curl http://localhost:4087/health
# → {"status":"ok"}
The /health endpoint is always open (no auth) and is used as the container liveness probe.
Connecting a remote MCP client
Point your MCP client at the /mcp endpoint with bearer token auth. For Claude Code, add the server to your .claude.json using the http transport type:
{
"mcpServers": {
"aex": {
"type": "http",
"url": "https://aex-mcp.your-domain.example/mcp",
"headers": {
"Authorization": "Bearer <MCP_BEARER_TOKEN>"
}
}
}
}
Container deployment
The production image exposes port 4087 and defaults to HTTP mode via ENV MCP_HTTP_PORT=4087. Inject the required environment variables through your Container App or Docker runtime — no .env file is used in production.
Next Steps
- MCP Tool Reference — complete parameter reference for all 43 tools
- Market Simulation — how to run AI trading personas and trigger market events