Model Context Protocol
Connect AI assistants with MCP
The Exponata MCP server lets Claude, ChatGPT, Cursor and other MCP clients answer questions about your stores, protocols, expectations and fill rates. It is read-only and uses the same organization API key as the Public Integration API.
Before you start
- An administrator creates an API key in the dashboard under Access → API keys. Copy it when it is shown; it starts with
exp_. Use a separate key per person or tool so you can revoke it independently. - Find your organization subdomain: the first part of your dashboard address. For
https://enata.asailabs.comit isenata. - Your MCP server URL is
https://<your-org>.asailabs.com/mcp. It uses the Streamable HTTP transport and reads the key from thex-auth-tokenheader. It also acceptsAuthorization: Bearer <key>and common alternatives such asx-api-key, so use whichever header your client lets you set.
Claude Code
export EXPONATA_API_KEY=exp_...
claude mcp add --transport http exponata https://<your-org>.asailabs.com/mcp \
--header "Authorization: Bearer $EXPONATA_API_KEY"Run claude mcp list to check the connection, then ask a question such as “Which stores are furthest below target this week?”. Add --scope user to make the server available in every project.
Claude Desktop
If your Claude organization offers Request headers when adding a custom connector (Settings → Connectors → Add custom connector), enter the server URL, pick the x-auth-token header and paste your key (exp_...) as the value.
Otherwise, connect through the mcp-remote bridge (requires Node.js). Edit claude_desktop_config.json (Settings → Developer → Edit Config) and restart Claude Desktop:
{
"mcpServers": {
"exponata": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://<your-org>.asailabs.com/mcp",
"--header",
"Authorization:${EXPONATA_AUTH}"
],
"env": {
"EXPONATA_AUTH": "Bearer exp_..."
}
}
}
}Keep Authorization: and the variable together without a space; some platforms split arguments on spaces.
ChatGPT
- Turn on developer mode: Settings → Security and login → Developer mode. Your workspace admin may need to allow custom MCP servers.
- Add a custom MCP server named Exponata with the URL
https://<your-org>.asailabs.com/mcp. - For authentication, choose the option that sends a fixed header: use
x-auth-tokenwith your key as the value, orAuthorizationwithBearer exp_....
The Exponata MCP server does not support OAuth yet. If your ChatGPT workspace only offers OAuth or no authentication for custom servers, ChatGPT cannot connect to it; use Claude or Cursor instead.
Cursor
Add the server to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). Cursor reads the key from your environment, so it stays out of the file:
{
"mcpServers": {
"exponata": {
"url": "https://<your-org>.asailabs.com/mcp",
"headers": {
"Authorization": "Bearer ${env:EXPONATA_API_KEY}"
}
}
}
}Local (stdio)
The same server also runs as a local process over stdio. This suits clients without remote MCP support and keeps traffic on your machine until it reaches the API. Ask Exponata support for the exponata-mcp.js bundle (Node.js 20 or later), then configure it with environment variables:
| Variable | Required | Description |
|---|---|---|
EXPONATA_API_KEY | Yes | Organization API key from Access → API keys. |
EXPONATA_ORG | Yes | Your organization subdomain, e.g. enata for https://enata.asailabs.com. |
EXPONATA_API_URL | No | Override the API origin. Defaults to https://<EXPONATA_ORG>.asailabs.com. |
EXPONATA_BASE_DOMAIN | No | Base domain for organization hosts. Defaults to asailabs.com. |
claude mcp add exponata \
--env EXPONATA_API_KEY=exp_... \
--env EXPONATA_ORG=<your-org> \
-- node /path/to/exponata-mcp.js{
"mcpServers": {
"exponata": {
"command": "node",
"args": ["/path/to/exponata-mcp.js"],
"env": {
"EXPONATA_API_KEY": "exp_...",
"EXPONATA_ORG": "<your-org>"
}
}
}
}Tools
All tools are read-only. Time ranges default to the last 7 days. Long results are summarised and paged; the assistant is told how to fetch the next page, so you can just ask follow-up questions.
| Tool | Use it for | Example question |
|---|---|---|
get_cross_store_fill_rates | Organization-wide fill rates by store, region, display type, category, day or week. | Which stores missed their targets this week? |
get_store_fill_rates | One store's fill rates by protocol, display or category, compared with expectations. | How is store 1042 doing this month? |
get_exposition_fill_rates | Photo-by-photo history of one display in one store. | How full was the drinks fridge at 1042 yesterday? |
list_store_protocols | Protocol runs for a store with status and average fill rate. | Did store 1042 submit all check-ins this week? |
get_protocol | One protocol run with its photos and per-photo results. | Why was this morning's protocol at 1042 so low? |
list_store_expectations | Fill-rate targets by display type, weekday and protocol time. | What are the Monday targets at 1042? |
list_stores | Page through stores to find external IDs. | Which stores do we have in Kraków? |
get_store | Store details: location, region, type and opening hours. | When is store 1042 open? |
list_store_expositions | Displays monitored in a store, with their IDs. | What displays does 1042 have? |
Security
- Every request is scoped to the organization that owns the API key. Revoke a key in Access → API keys to cut off access immediately.
- The server only reads data. It never returns store login codes or store contact details.
- Store keys in environment variables or your client's secret storage, not in files you commit.
- Requests count towards the Public Integration API rate limit.
Troubleshooting
- “The API key was rejected”
- The key is wrong, revoked, or belongs to another organization. Create a new key and update your client configuration.
- “Unknown organization”
- The server URL must use your organization subdomain, e.g.
https://enata.asailabs.com/mcp. - “Rate limited”
- Wait for the time shown and ask narrower questions, e.g. a shorter time range or fewer stores.
- The client tries to sign in with OAuth
- Check that the x-auth-token or Authorization header is configured. Without it, some clients fall back to an OAuth flow, which this server does not offer.