npm package: @justanalyticsapp/mcp-server
Description: MCP server for JustAnalytics — query analytics, errors, traces, logs, and metrics from your AI-powered IDE
Latest version: 0.2.0

# @justanalyticsapp/mcp-server

MCP (Model Context Protocol) server for [JustAnalytics](https://justanalytics.app) — query your analytics, errors, traces, logs, and infrastructure metrics directly from AI-powered IDEs like Claude Desktop, Cursor, Windsurf, and VS Code.

## Quick Start

```bash
# Set your API key
export JUSTANALYTICS_API_KEY=ja_sk_your_key_here

# Run with npx (no install required)
npx @justanalyticsapp/mcp-server
```

## IDE Configuration

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "justanalytics": {
      "command": "npx",
      "args": ["-y", "@justanalyticsapp/mcp-server"],
      "env": {
        "JUSTANALYTICS_API_KEY": "ja_sk_your_key_here",
        "JUSTANALYTICS_BASE_URL": "https://your-instance.justanalytics.app"
      }
    }
  }
}
```

### Cursor

Add to `.cursor/mcp.json` in your project root:

```json
{
  "mcpServers": {
    "justanalytics": {
      "command": "npx",
      "args": ["-y", "@justanalyticsapp/mcp-server"],
      "env": {
        "JUSTANALYTICS_API_KEY": "ja_sk_your_key_here",
        "JUSTANALYTICS_BASE_URL": "https://your-instance.justanalytics.app"
      }
    }
  }
}
```

### Windsurf

Add to `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "justanalytics": {
      "command": "npx",
      "args": ["-y", "@justanalyticsapp/mcp-server"],
      "env": {
        "JUSTANALYTICS_API_KEY": "ja_sk_your_key_here",
        "JUSTANALYTICS_BASE_URL": "https://your-instance.justanalytics.app"
      }
    }
  }
}
```

### VS Code

Add to `.vscode/mcp.json` in your project root:

```json
{
  "servers": {
    "justanalytics": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@justanalyticsapp/mcp-server"],
      "env": {
        "JUSTANALYTICS_API_KEY": "ja_sk_your_key_here",
        "JUSTANALYTICS_BASE_URL": "https://your-instance.justanalytics.app"
      }
    }
  }
}
```

### HTTP Transport (Remote MCP)

For cloud-hosted IDEs or custom integrations, use the HTTP transport endpoint at `/api/mcp` instead of stdio:

```bash
# The HTTP transport endpoint accepts MCP JSON-RPC messages
curl -X POST https://your-instance.justanalytics.app/api/mcp \
  -H "Authorization: Bearer ja_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

IDEs that support remote MCP via HTTP can be configured to point at your `/api/mcp` URL with the API key in the Authorization header.

## Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `JUSTANALYTICS_API_KEY` | Yes (or `--api-key`) | -- | API key for authentication. Create at Dashboard > Settings > API Keys |
| `JUSTANALYTICS_BASE_URL` | No (or `--base-url`) | `https://justanalytics.app` | Base URL of your JustAnalytics instance |

## CLI Arguments

| Argument | Description |
|----------|-------------|
| `--api-key <key>` | API key (overrides `JUSTANALYTICS_API_KEY` env var) |
| `--base-url <url>` | Base URL (overrides `JUSTANALYTICS_BASE_URL` env var) |
| `--help`, `-h` | Show help message |
| `--version`, `-v` | Show version number |

## Available Tools (25)

All tools are available via MCP (stdio and HTTP transport), REST execute endpoint (`/api/ai/execute`), and AI chat (`/api/ai/chat`).

### Analytics (5 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `analytics_realtime_stats` | Get real-time visitor count, active pages, top sources, and engagement metrics | `segmentId?` (string) |
| `analytics_historical` | Get historical pageviews, visitors, sessions, and bounce rate for a date range | `startDate` (string, ISO 8601, required), `endDate` (string, ISO 8601, required), `granularity?` ("hourly" \| "daily"), `segmentId?` (string) |
| `analytics_top_pages` | Get top pages ranked by views with unique visitors, bounce rate, and avg time | `startDate?` (string), `endDate?` (string), `limit?` (int, 1-100, default 50), `offset?` (int), `search?` (string), `segmentId?` (string) |
| `analytics_traffic_sources` | Get traffic sources breakdown by referrer with sessions, visitors, and category | `startDate?` (string), `endDate?` (string), `limit?` (int, 1-100, default 50), `segmentId?` (string) |
| `analytics_geo` | Get geographic distribution of visitors by country with pageviews and sessions | `startDate?` (string), `endDate?` (string), `limit?` (int, 1-100, default 50), `segmentId?` (string) |

### Errors (4 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `errors_list_groups` | List error groups with occurrence count, status, priority, and first/last seen | `page?` (int, default 1), `pageSize?` (int, 1-100, default 20), `status?` ("unresolved" \| "in_progress" \| "resolved" \| "ignored"), `search?` (string), `release?` (string), `environment?` ("production" \| "staging" \| "development"), `browser?` (string), `os?` (string), `deviceType?` ("mobile" \| "tablet" \| "desktop" \| "smarttv" \| "wearable" \| "console"), `handled?` (string), `priority?` ("critical" \| "high" \| "medium" \| "low" \| "unset"), `assignedTo?` (string) |
| `errors_get_detail` | Get full details for an error group including stack trace, timeline, and affected URLs | `errorGroupId` (string, required) |
| `errors_get_trends` | Get error occurrence trends over time with total count and trend percentage | `timeRange?` (string, e.g., "1h", "24h", "7d", "30d"), `environment?` (string) |
| `errors_get_latest` | Get the most recent error groups sorted by last seen time | `page?` (int, default 1), `pageSize?` (int, 1-100, default 20), `status?` ("unresolved" \| "in_progress" \| "resolved" \| "ignored") |

### Traces (3 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `traces_list` | List distributed traces with duration, span count, status, and service name | `timeRange?` (string), `service?` (string), `status?` ("ok" \| "error"), `hasError?` (boolean), `minDuration?` (number, ms), `maxDuration?` (number, ms), `limit?` (int, 1-100, default 50), `cursor?` (string), `search?` (string) |
| `traces_get_detail` | Get full trace waterfall with all spans, attributes, timing, and events | `traceId` (string, required) |
| `traces_service_map` | Get service dependency map with request counts and error rates between services | `timeRange?` (string) |

### Logs (2 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `logs_search` | Search logs by level, message, service, and time range with pagination | `timeRange?` (string), `level?` ("debug" \| "info" \| "warn" \| "error" \| "fatal"), `service?` (string), `search?` (string), `traceId?` (string), `limit?` (int, 1-100, default 50), `cursor?` (string) |
| `logs_stats` | Get log volume statistics by level and service with trend percentage | `timeRange?` (string), `service?` (string) |

### APM (2 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `apm_overview` | Get APM overview: p50/p75/p95/p99 latency, throughput, error rate per service | `timeRange?` (string), `service?` (string) |
| `apm_timeseries` | Get APM metrics timeseries for latency, throughput, or error rate over time | `timeRange?` (string), `service?` (string), `metric?` ("latency" \| "throughput" \| "errorRate") |

### Infrastructure (2 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `infra_metrics` | Get infrastructure metrics time-series data (CPU, memory, disk, network) for hosts | `metricName` (string, required, e.g., "cpu.user_percent", "memory.rss"), `timeRange?` (string), `host?` (string) |
| `infra_summary` | Get infrastructure summary: host count, latest CPU/memory values, and averages | _(none)_ |

### Alerts (2 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `alerts_list_rules` | List alert rules with status, conditions, thresholds, and last triggered time | _(none)_ |
| `alerts_list_events` | List alert events (fired/resolved) with timestamps, values, and thresholds | `ruleId?` (string), `limit?` (int, 1-100, default 50), `cursor?` (string) |

### Uptime (2 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `uptime_list_monitors` | List uptime monitors with current status, 24h availability, and avg response time | _(none)_ |
| `uptime_get_history` | Get uptime check history for a monitor with response times and availability | `monitorId` (string, required), `timeRange?` (string) |

### Conversions (2 tools)

| Tool | Description | Parameters |
|------|-------------|------------|
| `conversions_goals` | Get conversion goals with completion rates, revenue, and trend percentages | `startDate?` (string), `endDate?` (string) |
| `conversions_attribution` | Get attribution data showing which channels drive conversions by model | `startDate?` (string), `endDate?` (string), `model?` ("first_touch" \| "last_touch" \| "linear"), `goalId?` (string), `segmentId?` (string) |

### Releases (1 tool)

| Tool | Description | Parameters |
|------|-------------|------------|
| `releases_list` | List releases with version, deploy time, error count, and regression status | `environment?` (string), `hasRegression?` (boolean), `limit?` (int, 1-100, default 20), `cursor?` (string) |

## Example Queries

Once connected, you can ask your AI assistant questions like:

- "What are the current real-time stats for my site?"
- "Show me the error groups that spiked in the last 24 hours"
- "What are the slowest traces from the last hour?"
- "Search logs for errors containing 'timeout' in the API service"
- "What's the p99 latency trend for the last 7 days?"
- "Are there any uptime monitors currently down?"
- "Which traffic sources drove the most conversions last month?"
- "Show me the infrastructure CPU usage for the last 6 hours"
- "What alert rules have fired recently?"
- "List the latest releases and check for regressions"

## AI REST API

JustAnalytics provides 4 REST endpoints for programmatic AI access. These can be used independently of the MCP server.

### Authentication

- **Session auth** (cookie): Used by the in-app AI chat panel. Requires user to be logged in via the web UI.
- **API key auth** (Bearer token): Used for programmatic access. Pass `Authorization: Bearer ja_sk_...` header.

### POST /api/ai/chat — Streaming AI Chat

Multi-turn conversation with SSE streaming. Requires session auth and AI subscription.

```bash
curl -X POST https://justanalytics.app/api/ai/chat \
  -H "Content-Type: application/json" \
  -H "Cookie: next-auth.session-token=YOUR_SESSION" \
  -d '{
    "siteId": "site_abc123",
    "message": "What are the top traffic sources this week?",
    "conversationHistory": [],
    "currentPage": "/dashboard"
  }'
```

**Response** (SSE stream):
```
data: {"type":"tool_call","tool":"analytics_traffic_sources","input":{"startDate":"2026-03-07","endDate":"2026-03-14"}}

data: {"type":"tool_result","tool":"analytics_traffic_sources","result":{"sources":[{"referrer":"google.com","sessions":1234}]}}

data: {"type":"text","content":"Your top traffic source this week is Google with 1,234 sessions..."}

data: {"type":"done","usage":{"inputTokens":1200,"outputTokens":350}}
```

### POST /api/ai/query — Single-Shot Query

One question, one answer. Requires API key with `ai` scope and AI subscription.

```bash
curl -X POST https://justanalytics.app/api/ai/query \
  -H "Authorization: Bearer ja_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "siteId": "site_abc123",
    "query": "What are the error trends for the last 24 hours?"
  }'
```

**Response:**
```json
{
  "answer": "In the last 24 hours, there were 47 errors across 3 error groups. Error volume is down 12.5% compared to the previous 24 hours.",
  "toolsCalled": ["errors_get_trends"],
  "data": [
    {
      "tool": "errors_get_trends",
      "result": { "totalErrors": 47, "trend": -12.5, "groups": 3 }
    }
  ],
  "usage": {
    "inputTokens": 1200,
    "outputTokens": 350,
    "remaining": 42
  }
}
```

### POST /api/ai/execute — Direct Tool Execution

Execute a tool by name without LLM involvement. No AI subscription required -- only needs `read` scope API key. Does not consume AI quota.

```bash
curl -X POST https://justanalytics.app/api/ai/execute \
  -H "Authorization: Bearer ja_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "siteId": "site_abc123",
    "tool": "analytics_realtime_stats",
    "params": {}
  }'
```

**Response:**
```json
{
  "tool": "analytics_realtime_stats",
  "result": {
    "activeVisitors": 42,
    "topPages": [
      { "path": "/", "visitors": 15 },
      { "path": "/pricing", "visitors": 8 }
    ],
    "topSources": [
      { "referrer": "google.com", "visitors": 12 }
    ]
  },
  "executedAt": "2026-03-14T10:30:00.000Z"
}
```

### GET /api/ai/tools — List Tool Definitions

Returns all 25 tool definitions with schemas. Supports Anthropic and OpenAI formats. Requires `read` scope API key.

```bash
# Anthropic format (default)
curl https://justanalytics.app/api/ai/tools \
  -H "Authorization: Bearer ja_sk_your_key_here"

# OpenAI format
curl "https://justanalytics.app/api/ai/tools?format=openai" \
  -H "Authorization: Bearer ja_sk_your_key_here"
```

**Response:**
```json
{
  "format": "anthropic",
  "tools": [
    {
      "name": "analytics_realtime_stats",
      "description": "Get real-time visitor count, active pages, top sources, and engagement metrics",
      "input_schema": {
        "type": "object",
        "properties": {
          "segmentId": { "type": "string", "description": "Optional segment ID to filter results" }
        }
      }
    }
  ],
  "count": 25
}
```

## Authentication

The MCP server authenticates with JustAnalytics using API keys. API keys:
- Start with `ja_sk_` prefix
- Are scoped to a single site
- Require at least `read` scope for MCP and tool execution
- Require `ai` scope for `/api/ai/query` (LLM-powered queries)
- Are sent as `Authorization: Bearer ja_sk_...` on every API call
- Are never logged to stdout/stderr

Create an API key at: **Dashboard > Settings > API Keys**

**Security notes:**
- Never commit API keys to version control
- Use environment variables or secret management tools
- Rotate keys regularly via the dashboard
- Each key is scoped to one site -- create separate keys for different sites

## Troubleshooting

### Common Issues

**"Invalid API key" error**
- Verify your API key starts with `ja_sk_`
- Check that the key has not been revoked in Dashboard > Settings > API Keys
- Ensure the key has `read` scope (required for all MCP operations)
- For `/api/ai/query`, ensure the key also has `ai` scope

**"siteId does not match API key"**
- Each API key is scoped to a single site. The `siteId` in your request must match the site the API key was created for
- Create a new API key if you need to query a different site

**MCP server not connecting in IDE**
- Verify `npx @justanalyticsapp/mcp-server` runs without errors in your terminal
- Check that environment variables are set correctly in the IDE config
- Restart the IDE after modifying MCP configuration files
- Check IDE logs for MCP connection errors

**"AI subscription required" (403)**
- The `/api/ai/chat` and `/api/ai/query` endpoints require an AI add-on subscription
- `/api/ai/execute` does NOT require AI subscription (only `read` scope)
- MCP tool execution does NOT require AI subscription
- Upgrade at Dashboard > Settings > Billing

**"AI query limit exceeded" (429)**
- AI chat and query endpoints are limited to 50 queries per day per user
- Limits reset daily at midnight UTC
- Use `/api/ai/execute` for unlimited direct tool calls (no AI quota consumed)

**Tools return empty data**
- Ensure your site has data ingested (tracking script installed, SDK configured)
- Check time range parameters -- default ranges vary by tool
- Verify site ownership matches the API key

### Verifying Your Setup

```bash
# 1. Test API key
curl -s https://justanalytics.app/api/ai/tools \
  -H "Authorization: Bearer ja_sk_your_key_here" | head -c 200

# 2. Test MCP health endpoint (no auth required)
curl -s https://justanalytics.app/api/mcp/health

# 3. Test direct tool execution
curl -s -X POST https://justanalytics.app/api/ai/execute \
  -H "Authorization: Bearer ja_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"YOUR_SITE_ID","tool":"analytics_realtime_stats","params":{}}' | python3 -m json.tool

# 4. Test MCP stdio transport locally
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | \
  JUSTANALYTICS_API_KEY=ja_sk_your_key_here npx @justanalyticsapp/mcp-server
```

## Development

```bash
# Install dependencies
cd packages/mcp-server
npm install

# Build
npm run build

# Watch mode
npm run dev

# Run tests
npm test
```

## License

MIT