Query Trademarks
query_trademarksSearch US trademark records from the USPTO database. Filter results by trademark text, owner name, international class, status, and filing date range to find relevant trademark information.
Instructions
Search US trademarks from the USPTO. Filter by mark text, owner name, international class, status, and filing/registration date range. Source: USPTO TSDR and bulk XML data, updated weekly.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mark_text | No | Trademark text/name (partial match, e.g. 'APPLE') | |
| owner_name | No | Trademark owner/applicant name (partial match) | |
| international_class | No | Nice Classification code (e.g. '009' for computers/electronics) | |
| status | No | Trademark status (e.g. REGISTERED, PENDING, ABANDONED, CANCELLED) | |
| date_from | No | Start date for filing/registration (YYYY-MM-DD) | |
| date_to | No | End date for filing/registration (YYYY-MM-DD) | |
| limit | No | Maximum results to return (default 25, max 100) |
Implementation Reference
- src/tools/trademarks.ts:28-104 (registration)Registration of the 'query_trademarks' tool on the MCP server via server.registerTool() with name 'query_trademarks', input schema, and handler.
export function registerTrademarkTools(server: McpServer): void { // ── Query trademarks ──────────────────────────────────────────────────── server.registerTool( "query_trademarks", { title: "Query Trademarks", description: "Search US trademarks from the USPTO. Filter by mark text, owner name, " + "international class, status, and filing/registration date range. " + "Source: USPTO TSDR and bulk XML data, updated weekly.", inputSchema: { mark_text: z .string() .optional() .describe("Trademark text/name (partial match, e.g. 'APPLE')"), owner_name: z .string() .optional() .describe("Trademark owner/applicant name (partial match)"), international_class: z .string() .optional() .describe("Nice Classification code (e.g. '009' for computers/electronics)"), status: z .string() .optional() .describe("Trademark status (e.g. REGISTERED, PENDING, ABANDONED, CANCELLED)"), date_from: z .string() .optional() .describe("Start date for filing/registration (YYYY-MM-DD)"), date_to: z .string() .optional() .describe("End date for filing/registration (YYYY-MM-DD)"), limit: z .number() .int() .min(1) .max(100) .optional() .describe("Maximum results to return (default 25, max 100)"), }, }, async ({ mark_text, owner_name, international_class, status, date_from, date_to, limit }) => { const res = await apiGet<TrademarkQueryResponse>("/api/v1/trademarks", { mark_text, owner_name, international_class, status, date_from, date_to, limit: limit ?? 25, }); if (!res.ok) { return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const { count, data } = res.data; const summary = `Found ${count} trademark(s).`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, ); - src/tools/trademarks.ts:73-103 (handler)Handler function for query_trademarks that accepts optional filters (mark_text, owner_name, international_class, status, date_from, date_to, limit) and calls apiGet to /api/v1/trademarks, returning results or error.
async ({ mark_text, owner_name, international_class, status, date_from, date_to, limit }) => { const res = await apiGet<TrademarkQueryResponse>("/api/v1/trademarks", { mark_text, owner_name, international_class, status, date_from, date_to, limit: limit ?? 25, }); if (!res.ok) { return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const { count, data } = res.data; const summary = `Found ${count} trademark(s).`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, - src/tools/trademarks.ts:39-71 (schema)Input schema definition for query_trademarks using Zod, defining optional string parameters (mark_text, owner_name, international_class, status, date_from, date_to) and an optional integer limit (1-100).
inputSchema: { mark_text: z .string() .optional() .describe("Trademark text/name (partial match, e.g. 'APPLE')"), owner_name: z .string() .optional() .describe("Trademark owner/applicant name (partial match)"), international_class: z .string() .optional() .describe("Nice Classification code (e.g. '009' for computers/electronics)"), status: z .string() .optional() .describe("Trademark status (e.g. REGISTERED, PENDING, ABANDONED, CANCELLED)"), date_from: z .string() .optional() .describe("Start date for filing/registration (YYYY-MM-DD)"), date_to: z .string() .optional() .describe("End date for filing/registration (YYYY-MM-DD)"), limit: z .number() .int() .min(1) .max(100) .optional() .describe("Maximum results to return (default 25, max 100)"), }, - src/tools/trademarks.ts:15-19 (helper)TypeScript interface TrademarkQueryResponse used by the handler to type the API response data.
interface TrademarkQueryResponse { dataset: string; count: number; data: Record<string, unknown>[]; } - src/client.ts:44-76 (helper)apiGet helper function used by the handler to make HTTP GET requests to the Verilex API.
export async function apiGet<T = unknown>( path: string, params?: Record<string, string | number | undefined>, ): Promise<ApiResponse<T>> { const url = buildUrl(path, params); const headers: Record<string, string> = { Accept: "application/json", "User-Agent": "verilex-mcp-server/0.1.0", }; // Forward x402 payment token if present in env (for paid endpoints) const paymentToken = process.env.VERILEX_PAYMENT_TOKEN; if (paymentToken) { headers["X-Payment-Token"] = paymentToken; } const res = await fetch(url, { headers }); const data = (await res.json()) as T; const stale = res.headers.get("X-Data-Stale"); const lastUpdated = res.headers.get("X-Data-Last-Updated"); const ageSeconds = res.headers.get("X-Data-Age-Seconds"); return { ok: res.ok, status: res.status, data, stale: stale === "true", lastUpdated: lastUpdated ?? undefined, ageSeconds: ageSeconds ? Number(ageSeconds) : undefined, }; }