Metadata-Version: 2.4
Name: anomalo-mcp
Version: 0.7.1
Summary: Anomalo MCP Server — data quality tools for Claude Desktop, Cursor, Gemini CLI, and other MCP clients
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: anomalo>=0.35.1
Requires-Dist: fastmcp>=3.0
Requires-Dist: requests
Provides-Extra: sentry
Requires-Dist: sentry-sdk; extra == "sentry"

# Anomalo MCP Server

Bring your Anomalo data quality deployment into Claude Desktop, Cursor, Gemini CLI, and other MCP clients. Ask natural-language questions about the tables Anomalo monitors, trigger check runs, and — if your deployment has AIDA enabled — let Anomalo's AI Data Analyst explore your data on your behalf.

---

## Quick start

### 1. Get an Anomalo API key

1. Log into your Anomalo instance in the browser.
2. Go to **Settings → API Keys**.
3. Click **Create API Key**, copy the token.

You'll also need your Anomalo instance hostname, such as `app.anomalo.com` or `acme.anomalo.com`. Use the **bare hostname** — no `https://`, no trailing slash.

### 2. Install `uv`

[`uv`](https://docs.astral.sh/uv/) is a small Python tool runner. Your MCP client will use it to launch this server on demand — you do not install `anomalo-mcp` yourself.

```sh
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows PowerShell
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```

If your environment doesn't allow piping a remote script into a shell, see [uv's installation docs](https://docs.astral.sh/uv/getting-started/installation/) for Homebrew, `pip`, and standalone-binary alternatives.

Verify:

```sh
uvx --version
```

### 3. Configure your MCP client

Pick your client and drop the `anomalo` server block into its MCP config. Replace `YOUR-INSTANCE.anomalo.com` and `your-api-key` with the values from step 1.

#### Claude Desktop

Edit your Claude Desktop config:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

Add the `anomalo` entry (merging with any existing `mcpServers` block):

```json
{
  "mcpServers": {
    "anomalo": {
      "command": "uvx",
      "args": ["anomalo-mcp"],
      "env": {
        "ANOMALO_INSTANCE_HOST": "YOUR-INSTANCE.anomalo.com",
        "ANOMALO_API_SECRET_TOKEN": "your-api-key"
      }
    }
  }
}
```

Save, then **fully quit and restart Claude Desktop** (not just close the window).

#### Cursor

Open Cursor Settings → **Features → Model Context Protocol** → **Add new MCP server**.

- **Name**: `anomalo`
- **Command**: `uvx`
- **Arguments**: `anomalo-mcp`
- **Environment variables**:
  - `ANOMALO_INSTANCE_HOST` → `YOUR-INSTANCE.anomalo.com`
  - `ANOMALO_API_SECRET_TOKEN` → `your-api-key`

#### Gemini CLI

Install the [`anomalo-gemini-extension`](https://github.com/datagravity-ai/anomalo-gemini-extension) — it wraps this MCP server for Gemini CLI and handles the config for you.

```sh
# Set env vars (one-time, or add to ~/.gemini/.env)
export ANOMALO_INSTANCE_HOST=YOUR-INSTANCE.anomalo.com
export ANOMALO_API_SECRET_TOKEN=your-api-key

# Install the extension
gemini extensions install \
  https://github.com/datagravity-ai/anomalo-gemini-extension --auto-update
```

#### Other MCP clients

Any client that supports standard `mcpServers` config works. Use the same shape as Claude Desktop above:

```json
"anomalo": {
  "command": "uvx",
  "args": ["anomalo-mcp"],
  "env": {
    "ANOMALO_INSTANCE_HOST": "...",
    "ANOMALO_API_SECRET_TOKEN": "..."
  }
}
```

### 4. Verify it works

In your MCP client, ask:

> *Use Anomalo to list the organizations I have access to.*

You should see your Anomalo orgs come back. If it fails, head to [Troubleshooting](#troubleshooting) below.

---

## What you get

**Always available:**

| Tool | What it does |
|---|---|
| `get_organizations` | List Anomalo organizations you can access. |
| `set_active_organization` | Switch the active org for subsequent calls. |
| `get_labels` | List labels configured in the active org. |
| `get_configured_tables` | Tables monitored in the active org (filter by label, name, or id). |
| `get_checks_for_table` | List the data quality checks configured on a table. |
| `run_data_quality_checks_on_table` | Trigger a check run on a table. |

**If your deployment has AIDA enabled:**

| Tool | What it does |
|---|---|
| `ask_aida` | Ask a natural-language question about a specific table. AIDA explores the data, runs SQL (with approval), and returns analysis. |
| `ask_aida_chunked` | Same question across parallel conversations — useful for "last N weeks" or "per-dimension" sweeps. |
| `list_aida_conversations` | See recent AIDA conversations for a table. |
| `approve_aida_query` | Manually approve a pending SQL query (fallback when your client can't render approval dialogs). |

Not seeing AIDA tools? Contact your Anomalo account team — AIDA is enabled per deployment.

---

## Troubleshooting

### "command not found: uvx" or "failed to spawn: anomalo-mcp"

`uv` isn't installed, or isn't on your shell's `PATH`. Re-run the install from [step 2](#2-install-uv), then **restart your MCP client**.

### "missing required environment variable(s): ANOMALO_INSTANCE_HOST, ANOMALO_API_SECRET_TOKEN"

Your MCP client launched the server but didn't pass the env vars. Double-check the `env` block in your client's config (the JSON for Claude Desktop, the UI for Cursor). Save and **restart the client** — most clients only re-read MCP config on startup.

### "401 Unauthorized" or "403 Forbidden"

Your API token is wrong, revoked, or lacks permissions.
- Confirm you pasted the full token (no stray whitespace).
- Make sure your account has at least "Viewer" role on the org whose tables you're asking about.
- If the token is recent, give it a minute — some deployments cache tokens briefly.

### DNS / connection errors

Check `ANOMALO_INSTANCE_HOST`. Use the **bare hostname** with no protocol or path:

- ✅ `app.anomalo.com`
- ✅ `acme.anomalo.com`
- ❌ `https://app.anomalo.com/`
- ❌ `app.anomalo.com/dashboard`

### Claude (or another client) says "I don't see any Anomalo tools"

You added the config but didn't fully restart the client. Close the app completely (Cmd-Q on macOS, quit from tray on Windows), then reopen.

### The server keeps timing out

Long-running AIDA analyses can hit the 5-minute MCP client timeout. For broad questions (many weeks of data, many dimensions), use `ask_aida_chunked` and have your assistant compose the partial answers.

### Still stuck?

Contact your Anomalo account team with the error text and your client logs. For Claude Desktop, MCP error logs live at `~/Library/Logs/Claude/mcp*.log` (macOS) or `%APPDATA%\Claude\logs\mcp*.log` (Windows).

---

## Environment variables

| Variable | Required | Description |
|---|---|---|
| `ANOMALO_INSTANCE_HOST` | yes | Your Anomalo hostname, e.g. `app.anomalo.com`. No `https://`, no trailing slash. |
| `ANOMALO_API_SECRET_TOKEN` | yes | API token from Settings → API Keys. |
| `SENTRY_DSN` | no | Enables Sentry error reporting (PII scrubbed). Requires the `[sentry]` extra: `uvx --with sentry-sdk anomalo-mcp`. |
| `AIDA_FETCH_FILES` | no | `true` to download AIDA CSV query results inline. Off by default so row-level data doesn't flow through your MCP client's context window. |
| `ANOMALO_EXPERIMENTAL_UNSTRUCTURED_TOOLS` | no | `1` to expose experimental unstructured-collection tools. |

---

## Developing from source

```sh
git clone https://github.com/datagravity-ai/dquality
cd dquality/anomalo_labs/anomalo-mcp
uv sync
uv run pytest tests
```

Running the local checkout against a real Anomalo instance:

```sh
ANOMALO_INSTANCE_HOST=... ANOMALO_API_SECRET_TOKEN=... uv run anomalo-mcp
```

Source checkouts also load `dev_plugins/` — internal-only tools not shipped on PyPI.

See [CHANGELOG.md](./CHANGELOG.md) for release notes.
