Skip to main content
Glama
ambo-sk

mcp-brandwatch

by ambo-sk
README.md
# mcp-brandwatch

MCP server for the Brandwatch **Consumer Research API**, **Data Upload API** and
**Analysis API**.

> 📋 **Reviewing this?** Start with **[IT-REVIEW.md](IT-REVIEW.md)** — architecture,
> auth model, risk assessment, tool inventory and the open decisions. This README is
> the operator quick-reference.

Two flavours:

- `worker/` — **remote server on Cloudflare Workers** (connector URL). Primary.
- `server.py` — local stdio server (subset). Legacy/local use.

## Remote server (Cloudflare Worker)

Deployed at: `https://mcp-brandwatch.gtm-ai.workers.dev`

Connector URL (secret path — treat as a credential, it is in `worker/.mcp-secret`):

```
https://mcp-brandwatch.gtm-ai.workers.dev/<MCP_SECRET>/mcp
```

`/sse` also available for legacy SSE clients. Requests without the secret prefix get 404.

### Secrets

```sh
cd worker
npx wrangler secret put BW_TOKEN        # long-lived API token — preferred
# or:
npx wrangler secret put BW_USERNAME
npx wrangler secret put BW_PASSWORD
npx wrangler secret put MCP_SECRET      # URL path key (already set)
```

Only "Regular" or "Admin" Brandwatch accounts can use the API. Tokens come from
`POST https://api.brandwatch.com/oauth/token` (`grant_type=api-password`,
`client_id=brandwatch-api-client`) and last ~1 year.

### Deploy / dev

```sh
cd worker
npm install --legacy-peer-deps
npm run deploy      # or: npm run dev
```

## Tools (55)

| Group | Tools |
|---|---|
| Account | `me`, `get_user`, `get_client` |
| Projects | `list_projects`, `get_project` |
| Queries | `list_queries`, `get_query`, `validate_query`, `create_query`, `update_query`, `delete_query` |
| Query groups | `list_query_groups`, `delete_query_group` |
| Tags | `list_tags`, `create_tag`, `delete_tag`, `backfill_tag` |
| Categories | `list_categories`, `create_category`, `delete_category`, `backfill_category` |
| Rules | `list_rules`, `get_rule`, `delete_rule` |
| Author/site/location lists | `list_groups`, `create_group`, `delete_group` |
| Workflow & alerts | `get_workflow`, `list_alerts`, `get_alert`, `create_alert`, `update_alert`, `delete_alert` |
| Mentions | `get_mentions` (paged + cursor, fulltext), `count_mentions`, `update_mentions` |
| Charts & insights | `chart`, `multi_aggregate_chart`, `topics`, `data_insights` (hashtags/emoticons/urls/mentionedauthors/sharedsites) |
| Metadata | `list_filters`, `list_metrics`, `search_locations`, `list_exclusion_snippets` |
| Data Upload | `list_content_sources`, `create_content_source`, `update_content_source`, `delete_content_source`, `upload_documents`, `delete_documents`, `content_upload_usage` |
| Analysis (billed per query) | `analysis_submit`, `analysis_result`, `analysis_usage` |
| Escape hatch | `brandwatch_request` (any method, any path) |

## Rate limit & optimisations baked in

- Consumer Research API: **30 calls / 10 min per client** (`x-rate-limit` headers).
  The worker appends `_rateLimit` to responses once usage hits 70% so the model backs off.
- Metadata endpoints (tags, categories, lists, filters, metrics, locations,
  exclusion snippets) cached in-memory 5 min — Brandwatch's own recommended practice.
- `multi_aggregate_chart` and `count_mentions` exist specifically to spend fewer calls.
- OAuth token cached per isolate; auto-refresh once on 401.
- Dates: ISO 8601 (`2024-01-01` or `2024-01-01T00:00:00.000+0000`). Analysis API
  ranges max 24h. Mentions pagination caps at 10,000 — use `cursor` beyond.

Refs: <https://developers.brandwatch.com/llms.txt>, Python client
[BrandwatchLtd/bcr-api](https://github.com/BrandwatchLtd/bcr-api).