Skip to main content
Glama
nyku

Competiflow MCP Server

by nyku
README.md
# Competiflow MCP Server

[MCP (Model Context Protocol)](https://modelcontextprotocol.io) server for [Competiflow](https://competiflow.com). Use competitor monitoring as tools in Cursor, Claude Desktop, Windsurf, and any MCP-compatible client.

Track competitors, run discovery, read the interpreted change feed, triage items, and pull workspace digests without leaving your AI client.

## Setup

Create an API key in the Competiflow dashboard under **API keys**, then add the server to your client config. `COMPETIFLOW_API_KEY` is the only variable you need.

### Cursor

Add to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "competiflow": {
      "command": "npx",
      "args": ["-y", "@competiflow/mcp-server"],
      "env": {
        "COMPETIFLOW_API_KEY": "sk_live_your_key_here"
      }
    }
  }
}
```

### Claude Desktop

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

```json
{
  "mcpServers": {
    "competiflow": {
      "command": "npx",
      "args": ["-y", "@competiflow/mcp-server"],
      "env": {
        "COMPETIFLOW_API_KEY": "sk_live_your_key_here"
      }
    }
  }
}
```

### Windsurf

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

```json
{
  "mcpServers": {
    "competiflow": {
      "command": "npx",
      "args": ["-y", "@competiflow/mcp-server"],
      "env": {
        "COMPETIFLOW_API_KEY": "sk_live_your_key_here"
      }
    }
  }
}
```

## Available Tools

| Tool | API | Description |
| --- | --- | --- |
| `list_workspaces` | `GET /v1/workspaces` | List workspaces with review counts |
| `create_workspace` | `POST /v1/workspaces` | Create a workspace (optional `product_url`) |
| `update_workspace` | `PATCH /v1/workspaces/:id` | Rename, set or clear `product_url`, or pause/resume every monitor |
| `delete_workspace` | `DELETE /v1/workspaces/:id` | Remove a workspace and all its history |
| `add_competitor` | `POST /v1/workspaces/:id/competitors` | Add a competitor by homepage URL. Async discovery, idempotent on duplicate URL |
| `list_competitors` | `GET /v1/workspaces/:id/competitors` | List competitors with monitors and `last_run` |
| `get_competitor` | `GET /v1/competitors/:id` | Read one competitor |
| `update_competitor` | `PATCH /v1/competitors/:id` | Set cadence or status on all its monitors |
| `delete_competitor` | `DELETE /v1/competitors/:id` | Remove a competitor and all its history |
| `list_monitors` | `GET /v1/monitors` | List monitors with status, cadence, and `last_run` |
| `get_monitor` | `GET /v1/monitors/:id` | Read one monitor. Pass `include` for capture evidence |
| `create_monitor` | `POST /v1/monitors` | Add a manual monitor on a specific URL |
| `update_monitor` | `PATCH /v1/monitors/:id` | Update URL, cadence, status, or `min_severity` |
| `delete_monitor` | `DELETE /v1/monitors/:id` | Remove a monitor and all its history |
| `check_monitor` | `POST /v1/monitors/:id/check` | Queue an on-demand check |
| `refresh_workspace` | `POST /v1/workspaces/:id/refresh` | Queue checks for active monitors |
| `list_changes` | `GET /v1/changes` | Change feed with `since`, filters, and `meta` counts |
| `get_change` | `GET /v1/changes/:id` | Full change. Pass `include` for capture or raw diff |
| `update_change` | `PATCH /v1/changes/:id` | Set `review_status` |
| `get_digest` | `GET /v1/workspaces/:id/digest` | Weekly workspace summary |

Every tool declares MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`), so clients can ask before running the `delete_*` tools.

## Prompts

| Prompt | Arguments | What it does |
| --- | --- | --- |
| `weekly_briefing` | `workspace_id?`, `period?` | Summarizes competitor activity for a period, most important first |
| `triage_changes` | `workspace_id?`, `min_severity?` | Walks the unreviewed inbox and proposes acknowledge or dismiss, then asks before updating |
| `track_competitor` | `url`, `workspace_id?` | Adds a competitor, waits for discovery, and reports what is monitored |

Without `workspace_id`, each prompt starts with `list_workspaces`.

## Resources

| URI | Type | Contents |
| --- | --- | --- |
| `competiflow://guide` | `text/markdown` | Agent guide: the typical flow, discovery, evidence, and delete versus pause |
| `competiflow://workspaces/{workspace_id}/digest` | `application/json` | 7-day digest of one workspace. Clients that list resources show one per workspace. |

## Typical flow

1. `list_workspaces` or `create_workspace` (optional `product_url` improves competitive context on changes).
2. `add_competitor` with a homepage URL.
3. `get_competitor` until `discovery_status` is `completed`.
4. `refresh_workspace` or `check_monitor` to pull fresh data.
5. `list_changes` with `since=7d` and `min_severity`, or `get_digest` for a summary.
6. `get_change` with `include` when you need evidence.
7. `update_change` to acknowledge or dismiss items.

## Discovery and idempotency

`add_competitor` starts discovery in the background and returns an acknowledgement, not the finished result. Poll `get_competitor` until `discovery_status` is `completed`.

A workspace runs one discovery at a time. Posting the same homepage URL again returns the existing competitor without starting a second run. If a different competitor is still discovering, the call returns `409 discovery_in_progress` with `active_competitor_id` so you know which one to poll.

## Evidence with `include`

`get_change` and `get_monitor` accept an `include` array to attach the underlying capture in one call:

| Token | Available on | Returns |
| --- | --- | --- |
| `capture` | `get_change`, `get_monitor` | Extracted fields from the snapshot |
| `capture_markdown` | `get_change`, `get_monitor` | Page markdown from the snapshot |
| `raw_diff` | `get_change` | Before and after diff for the change |

For a change the capture is the post-change page. For a monitor it is the latest successful check, which is the current baseline.

## Delete versus pause

`delete_monitor`, `delete_competitor`, and `delete_workspace` are permanent. They remove the record along with its check runs, snapshots, and changes. To stop checks while keeping intel history, call `update_monitor`, `update_competitor`, or `update_workspace` with `status: paused` instead.

`delete_workspace` returns `409 discovery_in_progress` while a competitor in the workspace is still being discovered.

## Agent guidelines (for AI clients)

- **Poll discovery, do not assume:** after `add_competitor`, poll `get_competitor` until `discovery_status` is `completed` before reading changes. On `409`, poll the `active_competitor_id` from the error.
- **Filter the feed:** pass `since` (`1d`, `7d`, `30d`, or ISO8601), `min_severity`, `monitor_type` (`homepage`, `blog`, `docs`, `changelog`, `pricing`), and `review_status` to `list_changes` instead of pulling everything. Use `meta.counts` for inbox totals and `next_cursor` to page.
- **Interpretation fields:** changes and digest items expose `why_it_matters` for competitive context. `recommended_action` was removed from the API.
- **Fetch evidence on demand:** only add `include` to `get_change` or `get_monitor` when you need the underlying capture. It adds payload.
- **Prefer pause over delete:** default to `status: paused` when a user wants to stop a monitor. Reserve `delete_*` for permanent removal, since it drops history.

## How it works

The server translates each tool call into a Competiflow v1 API request and returns structured JSON. Your agent sees interpreted changes, severity, and why it matters instead of raw page scrapes.

```
AI Agent → MCP Tool Call → Competiflow API → Interpreted Change Feed → Structured Response → AI Agent
```

## Environment variables

| Variable | Required | Description |
| --- | --- | --- |
| `COMPETIFLOW_API_KEY` | Yes | Your Competiflow API key (`sk_live_...`) |

## Get an API key

Sign up at [competiflow.com](https://competiflow.com) and create a key under **API keys**.

## Development

```bash
npm install
npm run build
COMPETIFLOW_API_KEY=sk_live_... node dist/index.js
```

`npm test` builds and runs a smoke test that starts the server without a key, the way directory scanners do, and checks the tools, annotations, prompts, and resources.

## License

MIT

TDQS

A4.2/5.0

Scored across 20 tools

Disambiguation5/5

Each tool maps to a distinct resource+action pair, and the descriptions actively disambiguate the closest neighbours (check_monitor vs refresh_workspace, list_competitors vs list_monitors, list_changes vs get_digest vs get_change, add_competitor vs create_monitor) with explicit 'use X instead' pointers. Pause-vs-delete semantics are also spelled out consistently across the three hierarchies, so an agent can select confidently.

Naming Consistency4/5

The set follows a predictable verb_noun pattern (list_/get_/create_/update_/delete_ + resource, plus check_/refresh_ actions), which reads cleanly. The only wrinkle is that creation uses two verbs — add_competitor alongside create_monitor/create_workspace — a minor inconsistency rather than a real hazard.

Tool Count4/5

Twenty tools is on the heavy side of the rubric, but it decomposes cleanly: near-complete CRUD across three resources (workspace, competitor, monitor) plus four change/digest tools and two on-demand check tools. Each tool earns its place; nothing looks like a redundant duplicate.

Completeness4/5

The surface covers full lifecycle management of workspaces, competitors, and monitors, plus change reading (list_changes, get_change), triage (update_change), and briefing (get_digest) with async discovery/refresh flows handled via polling and explicit status codes. Minor gaps remain: there is no get_workspace for a single workspace by id (only list_workspaces), and change triage is one-at-a-time with no bulk operation.

Maintenance

ActivityMaintained
ResponsivenessNo issues