search_patents
Pack: patents · Connect: https://pipeworx.io/mcp (see Connect below for a single-pack URL)
No MCP client? Call it directly: GET https://gateway.pipeworx.io/v1/tools/search_patents for the schema, then POST the same URL with its arguments for the data.
Search USPTO patent applications and grants — without a granted_after/granted_before bound this returns the APPLICATION corpus sorted newest-FILED-first, not issued patents. USPTO publishes an application ~18 months after filing and typically takes 2+ years to grant it, so the newest rows in an unfiltered search are always recent, unexamined filings with grant_date: null — that is expected, not stale data. Pick the date field on the QUESTION’S VERB, not on the word “recent”: a question asking who has FILED / applied for / sought patents in a window wants filed_after/filed_before — the default application corpus already includes pending AND granted patents, so no granted_after is needed or wanted, and adding one will silently drop recently-filed-but-not-yet-examined applications (grant lags filing by 2+ years, so “filed in the last 3 years” AND “granted in the last 3 years” are mostly DISJOINT sets). Only use granted_after/granted_before when the question explicitly says GRANTED / ISSUED / APPROVED / “has a patent” (not just “recent patents”). Use query for free-text keywords (“lithium battery”, “crispr”, “machine learning”); all terms are required (AND), and you can quote a phrase to keep it together. A curated, short list of known synonym/abbreviation pairs for concepts that patents describe inconsistently (e.g. cfRNA / cell-free RNA / circulating RNA; MRD / minimal residual disease / residual cancer) is recognized in query — quoted or bare — and expanded to an OR group before the search runs, so “cfRNA” and “cell-free RNA” are treated as the same concept rather than requiring the caller to guess a specific patent’s exact wording (marked synonyms_expanded: true in the response; this is a fixed, documented list, not general synonym invention). A question that names several DISTINCT ways of describing the same idea (e.g. a condition plus a detection method, each expressed as its own quoted phrase) should still be passed as one query — if the literal AND-of-everything match returns zero, the tool automatically retries once with those same quoted phrases OR’d together instead and marks the response broadened: true; it only ever relaxes multi-phrase AND to OR on a genuine zero, so a search that is narrow for a real reason (e.g. one specific applicant with no matching filings, or an ordinary bare-keyword AND) still correctly returns zero. Optional structured filters: applicant (exact corporate name as filed, e.g. “APPLE INC.”), inventor (person name), title (words in the invention title), number (a specific application number), filed_after / filed_before, granted_after / granted_before. Common synonyms are understood — assignee, company and owner all reach applicant, and keywords, q or text all reach query. Results include title, application number, filing date, first applicant, all applicants, inventors, status, classification. total is the full match count but USPTO returns at most 25 records per search — narrow with applicant or a date range rather than raising limit. Powered by the USPTO Open Data Portal (data.uspto.gov).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | no | Free-text keywords. Every term must appear (they are AND-ed), so add words to narrow and remove words to widen. Wrap words in double quotes to require them adjacent: "machine learning" model needs the exact phrase plus the word model. Examples: “lithium battery”, “crispr”, “neural network”. Pass ”*” if you only want to filter by applicant/date with no keyword constraint. A curated set of known synonyms/abbreviations (e.g. cfRNA / cell-free RNA / circulating RNA, or MRD / minimal residual disease / residual cancer) is automatically expanded to an OR group within the query — quoted or bare, either form is recognized — so you do not need to guess which exact wording a given patent uses (see synonyms_expanded in the response). If several quoted phrases — or two recognized synonym-group concepts, quoted or not — ANDed together still match nothing, the tool retries once with them OR’d instead (see broadened in the response) rather than returning a bare zero. |
applicant | string | no | Optional. Company applicant name as it appears on the USPTO filing. This is also how to list the patents a company OWNS or holds (“patents assigned to X”, “X’s patents”, “patents owned by X”): set applicant, with query ”*” if there is no keyword. Must include the exact corporate suffix the company uses (PBC / Inc. / LLC / Corporation / Co. / NV / AG / KK). A wrong or missing suffix matches nothing — “Apple” returns zero where “APPLE INC.” returns hundreds. Examples: “Anthropic, PBC” (not “Anthropic Inc.”), “Apple Inc.” (not “Apple”), “Alphabet Inc.” (not “Google”), “Meta Platforms, Inc.” (not “Facebook”), “Microsoft Corporation” (not “Microsoft Corp.”). If you get zero results plus a warning field, the name form is wrong rather than the company being absent — retry with a different corporate form. |
inventor | string | no | Optional. Inventor name as recorded on the filing; a last name matches most reliably. Examples: “Hinton”, “Bengio”. Accepted synonyms: inventor_name, author. |
title | string | no | Optional. Words that must appear in the invention title, which narrows far harder than query does since query searches the whole record. Example: “solid state battery”. |
number | string | no | Optional. A specific US application number, digits only or formatted — “16123456” or “16/123,456”. Accepted synonyms: application_number, patent_number. |
filed_after | string | no | Optional. Filter to patents FILED on/after this date (ISO YYYY-MM-DD). Use this for “who has filed / applied for patents on X (recently / in the last N years)” — it covers both pending applications and already-granted patents, so it is the right bound even when the question also says “recent”. Do NOT substitute granted_after for a filing-activity question: grant lags filing by 2+ years, so a recent filing window under granted_after typically returns zero even when filing activity is real. |
filed_before | string | no | Optional. Filter to patents FILED on/before this date (ISO YYYY-MM-DD). |
granted_after | string | no | Optional. Filter to patents GRANTED (issued) on/after this date (ISO YYYY-MM-DD) — use ONLY when the question explicitly says GRANTED / ISSUED / APPROVED, not for a plain “recent patents” or “who has filed” question (use filed_after for those — see its description). Accepted synonym: issued_after. |
granted_before | string | no | Optional. Filter to patents GRANTED (issued) on/before this date (ISO YYYY-MM-DD). Accepted synonym: issued_before. |
limit | number | no | Number of results to return (default 10). USPTO caps every search at 25 records, so values above 25 have no effect — use the filters to narrow instead. |
_apiKey | string | no | USPTO ODP API key. Get free at https://data.uspto.gov/myodp. Falls back to platform key if configured. |
Example call
Arguments
{
"query": "\"cell-free RNA\"",
"filed_after": "2023-09-25",
"filed_before": "2026-09-25"
}
curl
curl -X POST https://gateway.pipeworx.io/patents/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_patents","arguments":{"query":"\"cell-free RNA\"","filed_after":"2023-09-25","filed_before":"2026-09-25"}}}'
TypeScript (@pipeworx/sdk)
import { Pipeworx } from '@pipeworx/sdk';
const pipeworx = new Pipeworx();
const result = await pipeworx.call('search_patents', {
"query": "\"cell-free RNA\"",
"filed_after": "2023-09-25",
"filed_before": "2026-09-25"
});
More examples
{
"query": "machine learning neural networks"
}
{
"query": "blockchain cryptocurrency"
}
{
"applicant": "APPLE INC."
}
{
"query": "neural",
"inventor": "Hinton"
}
Response shape
Always returns: query, filters, total, returned, results, patents
| Field | Type | Description |
|---|---|---|
query | string | The composed ODP query string actually sent |
filters | object | Echo of the structured filters applied; each is null when unused |
total | number | Total number of matching applications (USPTO ODP returns at most 25 records per search regardless of limit) |
returned | number | Number of records in this response |
note | string | Present when total exceeds the returned records — explains the 25-record ODP page cap |
warning | string | Present when an applicant filter matched nothing — ODP matches the corporate name literally (“APPLE INC.” not “Apple”) |
results | array | Back-compat summary shape (title, number, dates, applicant) |
patents | array | Same records with full ODP fields |
Full JSON Schema
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The composed ODP query string actually sent"
},
"filters": {
"type": "object",
"description": "Echo of the structured filters applied; each is null when unused",
"properties": {
"applicant": {
"type": [
"string",
"null"
]
},
"filed_after": {
"type": [
"string",
"null"
]
},
"filed_before": {
"type": [
"string",
"null"
]
},
"granted_after": {
"type": [
"string",
"null"
]
},
"granted_before": {
"type": [
"string",
"null"
]
}
}
},
"total": {
"type": "number",
"description": "Total number of matching applications (USPTO ODP returns at most 25 records per search regardless of limit)"
},
"returned": {
"type": "number",
"description": "Number of records in this response"
},
"note": {
"type": "string",
"description": "Present when total exceeds the returned records — explains the 25-record ODP page cap"
},
"warning": {
"type": "string",
"description": "Present when an applicant filter matched nothing — ODP matches the corporate name literally (\"APPLE INC.\" not \"Apple\")"
},
"results": {
"type": "array",
"description": "Back-compat summary shape (title, number, dates, applicant)",
"items": {
"type": "object"
}
},
"patents": {
"type": "array",
"description": "Same records with full ODP fields",
"items": {
"type": "object",
"properties": {
"patent_number": {
"type": "string",
"description": "Patent number"
},
"title": {
"type": "string",
"description": "Patent title"
},
"date": {
"type": [
"string",
"null"
],
"description": "Patent filing date or null"
},
"inventors": {
"type": "array",
"description": "List of inventors",
"items": {
"type": "object",
"properties": {
"first_name": {
"type": [
"string",
"null"
],
"description": "Inventor first name or null"
},
"last_name": {
"type": [
"string",
"null"
],
"description": "Inventor last name or null"
}
}
}
},
"assignee_organization": {
"type": [
"string",
"null"
],
"description": "Assignee organization name or null"
}
},
"required": [
"patent_number",
"title",
"date",
"inventors",
"assignee_organization"
]
}
}
},
"required": [
"query",
"filters",
"total",
"returned",
"results",
"patents"
]
}
Connect
Add this to your MCP client config — every tool in the catalog, including this one — or use one-click install buttons:
{
"mcpServers": {
"pipeworx": {
"url": "https://pipeworx.io/mcp"
}
}
}
Connect to just the patents pack
{
"mcpServers": {
"patents": {
"url": "https://gateway.pipeworx.io/patents/mcp"
}
}
}
See Getting Started for client-specific install steps.