# Trademark Dispute MCP Server (`nexgenwatch/trademark-dispute-mcp`) Actor

Answer 'has anyone contested a mark like this' across the USPTO Trademark Trial and Appeal Board and the Canadian Trademarks Opposition Board. Reports disputes, not clearance.

- **URL**: https://apify.com/nexgenwatch/trademark-dispute-mcp.md
- **Developed by:** [NexGen Watch](https://apify.com/nexgenwatch) (community)
- **Categories:** Agents, Business
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 tool calls

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Trademark Dispute MCP Server

Answer **"has anyone contested a mark like this"** across two public dispute registers — the
**USPTO Trademark Trial and Appeal Board** (TTABVUE) and the **Canadian Trademarks
Opposition Board** — live.

Built for naming and brand work.

### Read this first: an absence of disputes is not clearance

This server reports marks that were **contested**. Most trademarks are never contested, so
zero results says nothing about whether a conflicting mark exists. **It does not clear a
name, does not search publication registers, and is not legal advice.** Every answer repeats
this.

**Why disputes and not publications.** There is no public, logged-out, key-free source for
recent US or Canadian trademark *publications*: USPTO's TSDR and Open Data APIs are
key-gated (401 / 403), its gazette and dataset portal are JavaScript shells, its bulk host is
unreachable, and CIPO's bulk file was last refreshed 2024-08-30 on a host whose TLS
certificate fails to verify. The dispute side of both registers **is** live and key-free, so
that is what this server does — and it says so rather than dressing disputes up as
clearance.

Neither route carries a **Nice classification**. If you need class-scoped clearance, this is
not that product.

### Five things this server gets right that a naive read gets wrong

Measured live on 2026-07-30.

#### 1. The Canadian `year` filter is ignored — proven control vs test

```
year=2026   -> 138 decisions, citation years {2026}
year=2025   -> 138 decisions, citation years {2026}   <- identical set
year=2015   -> 138 decisions, citation years {2026}   <- identical set
no year     -> 138 decisions, citation years {2026}
```

`month` is ignored too; only `page` is real. So **this server offers no year filter** — it
would be selling a parameter the source discards. Its Canadian scope is exactly what the
board currently lists, and every answer reports the real date range it read.

#### 2. The Canadian listing renders inside an iframe

```
nav_date.do?page=1              -> 200, 25,076 B, ZERO decision links
nav_date.do?iframe=true&page=1  -> 200, 44,539 B, 25 decisions
```

Without `iframe=true` the source returns a perfectly healthy 200-OK page of site chrome with
no decisions in it. A page told to hold results and holding none is treated as a **failure**
here, never as "no disputes".

#### 3. The US result count is capped at "100+", so it is not a count

```
qs=nike      -> "Number of results: 100+"   (a cap)
qs=kombucha  -> "Number of results: 56"     (a real number)
```

A capped count is reported as a **floor**, never as a total.

#### 4. The US search runs over proceeding documents, not the mark

The source echoes your query as *"Document contains all words: NIKE"*. On page 1 of that
search the marks are DNK, DUNK, MIGHT DO IT, JUST DO IT — and only **7 of 116 marks on the
page contain "nike"**. That is the useful behaviour (these are the marks that got contested)
but it looks broken if you expect a mark-name search. So every row reports **separately**
whether your query appears in a **mark** or only in a **party name** — the first is the
signal a naming buyer wants; the second is much weaker.

#### 5. Canadian filtering is client-side, and the sweep reports its own completeness

The board's search endpoints 404 — three shapes tried. The only working route is the paged
listing, so the name filter is applied here over a complete sweep (measured: **138
decisions, 6 pages, ~256 KB**), and every answer states how many decisions were searched.

**The Canadian host also throttles**: a sweep at 2 requests/second earned an HTTP 403
partway through. It runs at **1 request/second** with bounded backoff, and if it still stops
short it returns **what it read plus the reason** — because "no disputes" from a partial
sweep is the most damaging wrong answer this product can give.

### Tools

| tool | what it answers |
|---|---|
| `check_mark` | Has anyone contested a mark like this — both registers in one call |
| `find_us_disputes` | TTAB proceedings mentioning a term: type, both parties, the marks at issue, serial and registration numbers |
| `find_canadian_disputes` | Opposition Board decisions, filtered by party or mark, with the scope actually searched |
| `explain_limits` | What this server will and will not say, and the five traps above. Read before acting. |

### Scope and pacing

`ttabvue.uspto.gov/robots.txt` is 404 — no rules. `decisions.opic-cipo.gc.ca/robots.txt` is
200 and disallows exactly two documents, neither in this collection. Each host has its own
strict-pacing bucket: **2 req/s** for the US, **1 req/s** for Canada, the latter because it
was measured throttling.

### Pricing

| Event | Price |
|---|---|
| Server start (`apify-actor-start`) | $0.05, charged once per server run by the platform |
| Tool call (`mcp-tool-call`) | **$0.05 flat per completed tool call** |

No other events. Memory is pinned to 1024 MB so the start fee is charged **once** — on this
platform the start event bills once per gigabyte.

**Errors and notices are not charged.** An empty name, an unknown source, a register read
failure, or a source throttle returns without billing.

**A sourced "no proceeding in either register mentions that name" IS charged** — that is the
answer a naming buyer is paying for.

If one register answers and the other fails, you get the answer **and** the named failure —
a partial read never looks whole.

If a tool call cannot be billed correctly, **the call fails** rather than serving free.

# Actor input Schema

## `note` (type: `string`):

This Actor runs as an MCP server in Standby mode. Connect an MCP client to the server URL with path /mcp; there is no batch input to fill in.

## Actor input object example

```json
{
  "note": "standby"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "note": "standby"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgenwatch/trademark-dispute-mcp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "note": "standby" }

# Run the Actor and wait for it to finish
run = client.actor("nexgenwatch/trademark-dispute-mcp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "note": "standby"
}' |
apify call nexgenwatch/trademark-dispute-mcp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgenwatch/trademark-dispute-mcp"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/fCfJhZXTWl0ecna01/builds/NHGNck81O3YpNeCk2/openapi.json
