Analytics MCP Guide

Connect Claude Code or Claude Desktop to the merged analytics database โ€” read-only, two-step setup.

What you get

An MCP (Model Context Protocol) server that lets Claude query the merged analytics MySQL cluster directly using natural language. Ask "how many bot trades happened yesterday?" and Claude writes the SQL, runs it, and explains the result. Read-only โ€” Claude can't write, update, delete, or run DDL even if it tries.

Schemas exposed:

  • pricing โ€” 7 tables, refreshed every 15 min (item_eod once daily).
  • steamarbitrage โ€” 51 tables, mostly refreshed every 15 min.
Compatibility
Claude Code
โœ“ Works
Claude Desktop
โœ“ Works
Cursor / Continue / Zed
โœ“ Works
claude.ai web
โœ“ Works (remote)
Two paths. Engineers on Claude Code / Cursor: keep using the local stdio path below (SSM tunnel + npx wrapper). Anyone on Claude Desktop or claude.ai web who doesn't want to install anything: jump to Remote (zero install) at the bottom โ€” three-step Custom Connector + Google SSO.
How it works

The cluster lives inside our VPC (eu-west-1c) and is not internet-accessible. To reach it from your laptop, you tunnel through the bastion using AWS Session Manager, then point the MCP server at localhost:13307. Claude talks to the MCP server over stdio, the MCP server talks to MySQL.

[ Claude Code / Desktop ] โ”‚ stdio [ analytics-mysql-mcp.sh ] โ† fetches password from Secrets Manager โ”‚ stdio [ npx @benborla29/mcp-server-mysql ] โ”‚ TCP [ 127.0.0.1:13307 ] โ† SSM port-forward (you keep open in another terminal) โ”‚ [ tradeit-analytics-merged ] โ† inside VPC, eu-west-1c
Before you start

You need:

  • AWS CLI signed in to account 037333185217, region eu-west-1. Verify with aws sts get-caller-identity.
  • Permissions: ssm:StartSession on the bastion + secretsmanager:GetSecretValue on tradeit-analytics/merged-aurora-analytics-ro. If you can't read the secret, ping Ehud.
  • Session Manager Plugin: brew install --cask session-manager-plugin (Mac) or install for Windows / Linux.
  • Node.js 18 or newer (for npx): brew install node or nvm install 20.
  • jq: brew install jq.
  • The tradeit-analytics repo cloned locally โ€” that's where the wrapper script lives.
Step 1 โ€” Open the SSM tunnel
1
Tunnel from your laptop to the cluster

Open a terminal and run this command. Leave it running โ€” closing this terminal closes the tunnel.

aws ssm start-session --target i-09307b996e59fc707 --region eu-west-1 \
  --document-name AWS-StartPortForwardingSessionToRemoteHost \
  --parameters 'host=tradeit-analytics-merged.cluster-crwayzab6rxf.eu-west-1.rds.amazonaws.com,portNumber=3306,localPortNumber=13307'

You should see Waiting for connections.... That's the tunnel โ€” your machine's localhost:13307 now points at the Aurora cluster.

Test it from another terminal:

nc -zv 127.0.0.1 13307
# Connection to 127.0.0.1 port 13307 [tcp/*] succeeded!
Heads-up: the tunnel disconnects after ~30 min of idle, after laptop sleep, or VPN flap. If MCP queries start failing, re-run the tunnel command. (For a one-line auto-restart pattern, see "Pro tip" at the bottom.)
Step 2 โ€” Wire it into your Claude
2
Add the MCP server to your config

The wrapper script lives at infra/mcp/analytics-mysql-mcp.sh in the tradeit-analytics repo. Get its absolute path:

cd ~/Projects/tradeit-analytics
realpath infra/mcp/analytics-mysql-mcp.sh
# /Users/you/Projects/tradeit-analytics/infra/mcp/analytics-mysql-mcp.sh

Then drop the snippet into the right config file for your client:

Edit ~/.claude.json and add the entry under mcpServers. Use the absolute path you printed above.

~/.claude.json
{
  "mcpServers": {
    "analytics-mysql": {
      "command": "/Users/you/Projects/tradeit-analytics/infra/mcp/analytics-mysql-mcp.sh"
    }
  }
}

If mcpServers already has other entries, add analytics-mysql alongside them. Save the file. Claude Code picks it up on the next session โ€” close and reopen, or claude from the terminal again.

Mac: edit ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

claude_desktop_config.json
{
  "mcpServers": {
    "analytics-mysql": {
      "command": "/Users/you/Projects/tradeit-analytics/infra/mcp/analytics-mysql-mcp.sh"
    }
  }
}

Restart Claude Desktop after saving. The MCP server appears as a tool the next time you start a chat.

Both Cursor and Continue support MCP over stdio. The exact config location varies by version; check their docs. The shape is identical:

"mcpServers": {
  "analytics-mysql": {
    "command": "/Users/you/Projects/tradeit-analytics/infra/mcp/analytics-mysql-mcp.sh"
  }
}
Step 3 โ€” Verify
3
Ask Claude something

Start a new Claude conversation and try one of these. The first time, Claude may ask to confirm using the new tool.

  • "List all tables in the steamarbitrage schema."
  • "How many rows are in pricing.bot_trade_item_logs?"
  • "Show me the watermark status โ€” table_name, last_run_at, status โ€” from pricing._repl_state."
  • "Top 10 affiliates by revenue in the last 7 days."

If the answers come back, you're connected. If you see a connect ECONNREFUSED error, your tunnel isn't running โ€” check Step 1.

What's queryable

Two schemas Claude can read. Freshness is replication-driven โ€” see the _repl_state table in each schema for live watermarks.

SchemaTablesCadenceNotes
pricing 7 + _repl_state 15 min (item_eod daily) Pricing engine inputs/outputs from pricing-test source.
steamarbitrage 51 + _repl_state 15 min (guess_questions 4-hourly) Trading lifecycle from steamarbitrage-cluster source.
PII not yet redacted. The analytics_ro user can read everything, including emails and Steam IDs. Treat MCP output as engineer-only until OPS-160 ships the analytics_safe redacted views.
Security & safety

Three layers of read-only enforcement:

  1. The analytics_ro MySQL user has SELECT grants only.
  2. The wrapper script forces ALLOW_INSERT_OPERATION=false, ALLOW_UPDATE_OPERATION=false, ALLOW_DELETE_OPERATION=false, ALLOW_DDL_OPERATION=false on every spawn.
  3. Per-query timeout 30s, 20 qps client-side rate limit.

The password is fetched fresh from Secrets Manager each time the MCP starts โ€” never written to disk in a config file.

Don't share your AWS credentials. The MCP wrapper uses your local AWS profile. If you let someone else's machine run this with your creds, they get analytics-ro access until you rotate. Each teammate sets up their own per the steps above.
Troubleshooting
SymptomFix
connect ECONNREFUSED 127.0.0.1:13307 Your SSM tunnel isn't running. Re-open it (Step 1).
AccessDenied โ€ฆ secretsmanager:GetSecretValue Your AWS user/role lacks the secret read permission. Ping Ehud to add the IAM policy.
npx: command not found Install Node.js 18+: brew install node.
jq: command not found brew install jq.
Claude doesn't see the MCP tool Restart Claude Code/Desktop. Confirm config file path is right (Mac vs Win) and JSON is valid.
Queries hang or time out Tunnel may have dropped silently. Run nc -zv 127.0.0.1 13307; if it fails, re-open the tunnel.
Authentication plugin error Set "env": { "MYSQL_AUTH_PLUGIN": "mysql_native_password" } in your Claude config block.
Pro tip โ€” auto-restart the tunnel

Drop this in a terminal tab and forget about it โ€” the tunnel reconnects every time it drops:

while true; do
  aws ssm start-session --target i-09307b996e59fc707 --region eu-west-1 \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters 'host=tradeit-analytics-merged.cluster-crwayzab6rxf.eu-west-1.rds.amazonaws.com,portNumber=3306,localPortNumber=13307'
  echo "tunnel dropped, reconnecting in 3sโ€ฆ"
  sleep 3
done

Or wrap it as a launchd job so it starts automatically on login. Ehud has a sample plist if you want it.

Remote (zero install) โ€” Claude Desktop & claude.ai web

For non-engineers (Product, Support) and anyone on claude.ai in the browser: there's nothing to install. The same MCP runs as a Fargate service behind Cloudflare Access (Google SSO, @zengaming.com). You add it as a Custom Connector once.

  1. Open Claude Desktop or claude.ai โ†’ Settings โ†’ Connectors โ†’ Add custom connector.
  2. URL: https://analytics-mcp.tradeit.gg/mcp  ยท  leave OAuth Client ID / Secret blank.
  3. Sign in with Google when the popup appears (use your @zengaming.com account). Done.

Verify the same way as Step 3 above: ask Claude "list tables in steamarbitrage" โ€” you should get back ~51 tables.

What's different from local. Same read-only analytics_ro credentials, same schemas, same 30s query timeout, same 20 qps per-user rate limit. No SSM tunnel, no AWS CLI, no Node. Per-query audit log captures your email in /ecs/analytics-mcp CloudWatch group.
Cost & scale. ARM64 Fargate (0.25 vCPU / 512 MB), eu-west-1c, autoscale 1-3 tasks. Roughly $8-15/mo all-in.
Links