wafle MCP server
Provides tools for exporting Google Ads and accessing analytics by period, as well as checking Google connection status.
Provides tools and prompts to connect Meta to a store, sync product catalog to Commerce Manager, export Meta audiences, and check Meta connection status.
Provides resource to check TikTok connection status in the ads connections.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@wafle MCP servershow me orders placed today"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@wafle/mcp — Model Context Protocol server for wafle
The first MCP server for the wafle commerce platform. Lets Claude Desktop, Claude Code, agents, and any MCP-compatible client drive a wafle tenant — stores, products, orders, pricing, gateways, audiences, system — by talking to it.
What this is
Wafle is the LLM-first multi-tenant commerce platform. Its REST API at https://wafle.click/wp-json/waffle/v1/ does the work; this MCP server exposes that work as 68 tools, 14 resources, and 5 server-defined prompts an LLM can pick from. Every wafle feature should land here as a tool first, UI second.
This is a thin, well-typed wrapper. No business logic lives in this package — bugs in pricing or order flow belong to the wafle backend.
Install
git clone <repo>
cd wafle-mcp
npm install
npm run buildConfigure
Set environment variables (or copy .env.example to .env):
WAFLE_API_URL=https://wafle.click/wp-json/waffle/v1 # default
WAFLE_API_KEY=<your wafle admin key> # required (upstream)
WAFLE_TIMEOUT_MS=30000 # optional
# Only used by --transport=http:
WAFLE_MCP_HTTP_HOST=0.0.0.0
WAFLE_MCP_HTTP_PORT=7100
# Tenant-scoped JWT auth (recommended). Same value as WAFFLE_MCP_JWT_SECRET
# in the backend mu-plugin. Generate: openssl rand -hex 64
WAFLE_MCP_JWT_SECRET=<shared HS256 secret>
WAFLE_MCP_REQUIRE_JWT=1 # refuses legacy bearers in prod
# Legacy admin-tier bearers (cross-tenant). Used as fallback when REQUIRE_JWT is unset.
WAFLE_MCP_TOKENS=<comma-separated bearer tokens>
LOG_LEVEL=infoWAFLE_API_KEY is the upstream wafle key the MCP server uses to talk to the backend (master, scoped at the backend layer). Tenant isolation for the MCP itself is enforced by WAFLE_MCP_JWT_SECRET — the backend mints HS256 JWTs carrying tenant_id + tenant_slug + scope, and this server filters tools/list and rewrites every per-store call to the JWT's tenant. See src/auth/jwt.ts, src/auth/tenant.ts.
Tenant tokens
Clients obtain a tenant-scoped JWT from the wafle backend:
POST /wp-json/waffle/v1/admin/account/mcp/issue-token
X-Wafle-Admin-Key: <store key for that tenant>
{ "ttl_days": 30 }Response includes { token, jti, tenant_slug, expires_at, mcp_url }. The client then sends Authorization: Bearer <token> to mcp.wafle.click/mcp. With this token:
tools/listonly shows the tenant's tools — admin-only tools (wafle_system_*,wafle_gateways_*,wafle_stores_list/create,wafle_auth_keys_*) are filtered out server-side.Every per-tenant tool ignores the
slugargument and uses the JWT'stenant_sluginstead. A token for tenant A cannot read or mutate tenant B regardless of arguments passed.Tokens can be revoked via
POST /admin/account/mcp/revoke-token({ jti }) and listed viaGET /admin/account/mcp/tokens.
Run
stdio (Claude Desktop, Claude Code local)
node dist/index.js --transport=stdioLogs go to stderr. Stdout is reserved for the JSON-RPC framing — never console.log from a tool handler.
HTTP / Streamable HTTP (remote agents, web)
node dist/index.js --transport=httpListens on WAFLE_MCP_HTTP_PORT (default 7100). Single endpoint at POST /mcp per the MCP Streamable HTTP spec (2025-03-26). GET /healthz for liveness.
Bearer auth on every request: Authorization: Bearer <token> where <token> is one of the values in WAFLE_MCP_TOKENS. The MCP server refuses all traffic if no tokens are configured.
Connect Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"wafle": {
"command": "node",
"args": ["/absolute/path/to/wafle-mcp/dist/index.js", "--transport=stdio"],
"env": {
"WAFLE_API_KEY": "your-wafle-admin-key",
"WAFLE_API_URL": "https://wafle.click/wp-json/waffle/v1",
"LOG_LEVEL": "info"
}
}
}
}Restart Claude Desktop. You should see "wafle" with 63 tools in the /mcp panel.
There is also an example at examples/claude-desktop-config.json.
Connect Claude Code
Project-scoped: drop a file at <repo>/.mcp.json:
{
"mcpServers": {
"wafle": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/wafle-mcp/dist/index.js", "--transport=stdio"],
"env": { "WAFLE_API_KEY": "your-key" }
}
}
}User-scoped: append to ~/.claude/.mcp.json (same shape).
For the deployed HTTP transport at mcp.wafle.click:
{
"mcpServers": {
"wafle": {
"type": "http",
"url": "https://mcp.wafle.click/mcp",
"headers": { "Authorization": "Bearer <bearer token>" }
}
}
}Tool catalogue (68)
Domain | Tools |
auth |
|
stores |
|
products |
|
pricing |
|
orders |
|
customers |
|
gateways |
|
shipping |
|
coupons |
|
abandoned |
|
analytics |
|
exports |
|
pixels |
|
system |
|
meta |
|
Every tool has a markdown description with usage guidance, a Zod schema with .describe()-annotated fields, scope requirements, and readOnlyHint/destructiveHint/idempotentHint annotations to help the LLM pick wisely.
The long-running tools (_sync_trigger_and_wait, _csv_import, _ads_sync_full) emit notifications/progress while polling — clients that support progress (Claude Desktop) show a live progress bar.
Resources (14)
MCP Resources expose read-only context the LLM can pull in without spending a tool call. Reference them with @<uri> in Claude Desktop or by URI in any client.
URI | TTL | Purpose |
| 30s | Backend health snapshot. |
| 1h | Catalog of every API scope (domain, tier, label). |
| 1h | REST canonical shapes. |
| 1h | Architecture overview. |
| 60s | Lean list of every store. |
| 60s | Full store snapshot (settings + 7d KPIs + abandoned + last order). |
| 30s | Last 20 orders with summary fields. |
| 60s | Top 20 abandoned carts. |
| 5min | 7-day analytics. |
| 5min | 30-day analytics. |
| 2min | Top 20 products. |
| 60s | Customer segments. |
| 60s | Last 10 campaigns. |
| 5min | Meta/Google/TikTok connection status. |
Cache is in-memory per session, with TTL per resource. Manual invalidation: wafle_resources_invalidate { uri_pattern }. Long-running tools auto-invalidate the affected store.
See docs/RESOURCES.md for full details and examples.
Prompts (5)
Server-defined parametric workflows for the most common BATTO operations. The client surfaces a picker; pick → fill args → conversation starts with a fully-rendered plan.
Name | Use case |
| End-to-end onboarding (store + MP + catalog + frontend API key). |
| Mark order shipped with tracking + customer email. |
| Build segment + create email campaign (immediate or scheduled). |
| Connect Meta to a store + sync catalog to Commerce Manager. |
| Diagnose failed payment + optionally retry via secondary gateway. |
See docs/PROMPTS.md for argument schemas and example invocations.
Conversational examples
See examples/prompts/:
01-onboarding-tienda-nueva.md — onboarding a new client end to end.
02-pedido-enviar.md — single-shot logistics action.
03-segmentar-y-campania.md — segment + campaign.
04-conectar-meta-y-sync.md — connect Meta + catalog sync.
05-debug-orden-fallida.md — payment failure diagnosis.
The 5 prompts above are converted to server-defined MCP prompts in src/prompts/.
Scopes
Each tool declares a scope (e.g. orders:write, gateways:admin). At startup the server calls wafle_auth_me to retrieve the granted scopes; if wafle's /auth/me returns type=master we grant ALL_SCOPES. If it returns neither scopes nor a known type, the server runs in warn-mode — scope checks are skipped and a startup warning is logged.
The full matrix lives in src/auth/scopes.ts.
Architecture
See ARCHITECTURE.md. TL;DR: thin TypeScript wrapper over wafle REST, Fastify for HTTP, the official @modelcontextprotocol/sdk, Zod for validation, pino for logs (stderr only — required for stdio).
Deploy
docker compose up -dor with the systemd unit at deploy/systemd/wafle-mcp.service. The repo includes Dockerfile (multistage, alpine runtime) and a sample nginx config for mcp.wafle.click.
Troubleshooting
401 waffle_unauthorized:WAFLE_API_KEYis missing or wrong. Get the master key from the waffle container at/root/.waffle-creds.txt.Claude Desktop says no tools: confirm the path in
claude_desktop_config.jsonis absolute anddist/index.jsexists. Runnode dist/index.js --transport=stdioin a terminal — if it doesn't start, fix the env first.Stdout corruption: don't
console.loganywhere. All logs must go viagetLogger()(which writes to stderr).HTTP transport refuses traffic: set
WAFLE_MCP_TOKENSand passAuthorization: Bearer <token>.Wafle says
forbidden, invalid master key: some endpoints (e.g./system/versions) check a different key. Verify withcurl -H "X-Wafle-Admin-Key: $KEY" https://wafle.click/wp-json/waffle/v1/auth/mefirst.
Development
npm run dev # tsx-watch, stdio
npm run dev:http # tsx-watch, http
npm test # vitest
npm run test:coverage
npm run lint
npm run typecheckLicense
MIT — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/the33warehouse-tech/wafle-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server