Skip to main content
Glama
USPTO Patent MCP Server

USPTO Patent MCP Server

by riemannzeta

USPTO Patent & Trademark MCP Server

An MCP server (Python SDK 2.x, MCPServer) for accessing United States Patent and Trademark Office (USPTO) patent and trademark data through multiple APIs including the Patent Public Search API, the Open Data Portal (ODP) API, PTAB API v3, the TSDR trademark status API, and USPTO trademark search. Using this server, Claude Desktop can pull data from USPTO APIs, search through PTAB proceedings and decisions, research prosecution history, run trademark clearance searches, track trademark status, and more:

Screen Capture of Claude Desktop using Patents MCP Server

For an introduction to MCP servers see Introducing the Model Context Protocol.

Special thanks to Parker Hancock, author of the amazing Patent Client project, for blazing the trail to understanding of the string of requests and responses needed to pull data through the Public Search API.

Features

This server provides 42 tools across six live USPTO data sources (23 more, for APIs USPTO has shut down, stay in the code behind ENABLE_LEGACY_TOOLS):

  1. Patent Search - Full-text search of granted patents and published applications via PPUBS

  2. Full Text Documents - Get the text of a patent by number, or just its claims, abstract or front page to save context

  3. PDF Downloads - Download patents as PDF files (Claude Desktop doesn't support this as a client currently)

  4. Prosecution History - Transactions, file-wrapper document lists filtered by type (office actions, responses, notices of allowance), and the documents themselves as plain text or PDF via ODP

  5. Office Action Search - Search 19.9M office actions (2007 on) by examiner language, rejection statute, art unit and date, with counts by document code and statute

  6. Claim-Level Rejections and Citations - Which claims each office action rejected, objected to or allowed and under which statute, with Alice/Mayo/Myriad/Bilski flags (2012 on), and the references each action cited, searchable in reverse to find every application whose examiner cited a given patent

  7. Petition Decisions - Search 1.1M decisions on patent petitions (revival, reinstatement, make special, supervisory review) by text, type, outcome and office

  8. Patent Family Data - Continuity information, foreign priority, and related applications

  9. Bulk Datasets - Search and access USPTO bulk data products including PatentsView disambiguated data

  10. Forward Citations - Find the later patents that cite a patent

  11. Trademark Search - Full-text search of US federal trademarks by mark text, owner, goods/services, and class (clearance/knockout searches)

  12. Trademark Status & Documents - Authoritative live status, prosecution documents, and mark images via TSDR

  13. Trademark Assignments - Recorded ownership transfer records from 1955 to present (no API key needed)

It runs locally over stdio for Claude Desktop and Claude Code, or over HTTP as a shared, stateless service — see Remote hosting over HTTP.

Note on unavailable APIs: The PatentsView API (search.patentsview.org) was shut down on March 20, 2026, with its data migrated to ODP bulk datasets. The Office Action and Enriched Citation APIs (developer.uspto.gov) were decommissioned in early 2026; office action search, rejections and citations have since returned on ODP (odp_search_office_actions, get_office_action_rejections, get_office_action_citations). The Patent Litigation API is not offered on the USPTO Open Data Portal; litigation data is available as a bulk download. The 23 affected tools stay in the code but are not registered by default, since their schemas cost every client about 6k tokens per session and they can only fail; set ENABLE_LEGACY_TOOLS=true to register them, and each returns workaround guidance pointing to a live tool.

Related MCP server: USPTO Patent MCP Server

API Sources

Source

Description

Auth Required

Status

ppubs.uspto.gov

Full text documents, PDF downloads, advanced search (daily updates)

No

Active

api.uspto.gov (ODP)

Metadata, continuity, transactions, assignments, prosecution history

Yes (ODP API Key)

Active

PTAB Trial API

IPR/PGR/CBM proceedings, decisions, appeals

Yes (ODP API Key)

Active (ODP v3.0)

tsdrapi.uspto.gov (TSDR)

Trademark status, prosecution documents, mark images

Yes (TSDR API Key — separate from ODP)

Active

tmsearch.uspto.gov

Full-text trademark search (internal API behind the TESS replacement)

No

Active (unofficial)

assignmentcenter.uspto.gov

Trademark ownership transfer records (1955-present)

No

Active

Patent Litigation API

74,000+ district court patent cases

N/A

Not offered on ODP (issue #16)

PatentsView API

Disambiguated inventor/assignee data, advanced search

N/A

Shut down March 2026

ODP Office Action Search

Office actions 2007 on: text search, statutes, art units (text returned to 500 chars)

Yes (ODP API Key)

Active (2026-10)

ODP Petition Decisions

Decisions on patent petitions, 1991 on

Yes (ODP API Key)

Active (2026-10)

ODP Office Action Rejections & Citations

Claim-level rejections (2012 on) and cited references per office action

Yes (ODP API Key)

Active (2026-10)

Office Action APIs (developer.uspto.gov)

Office action text and search

N/A

Decommissioned early 2026

Prerequisites

  • Python 3.10-3.13 (3.12 recommended); the server builds on the MCP Python SDK 2.x (mcp>=2,<3)

  • Claude Desktop (for integration). Other models and MCP clients have not been tested.

  • UV for Python version and dependency management

If you're a Python developer but still unfamiliar with uv, you're in for a treat. It's faster and easier than having a separate Python version manager (like pyenv) and setting up, activating, and maintaining virtual environments with venv and pip.

If you don't already have uv installed:

curl -LsSf https://astral.sh/uv/install.sh | sh

Installation

From PyPI (no clone needed)

uvx downloads and runs the published package on demand. Point Claude Desktop at it in claude_desktop_config.json, passing your API keys in the environment:

{
  "mcpServers": {
    "patents": {
      "command": "uvx",
      "args": ["patent-mcp-server"],
      "env": {
        "USPTO_API_KEY": "your_odp_key",
        "TSDR_API_KEY": "your_tsdr_key"
      }
    }
  }
}

or in Claude Code:

claude mcp add patents -e USPTO_API_KEY=your_odp_key -e TSDR_API_KEY=your_tsdr_key -- uvx patent-mcp-server

The keys are optional (see API Key Setup); the PPUBS patent tools, trademark search and assignment search work without any. A .env file is read from the working directory, which under uvx is wherever the client started the server, so pass keys through env as above.

From source

  1. Clone this repository:

    git clone https://github.com/riemannzeta/patent_mcp_server
    cd patent_mcp_server
  2. Install dependencies with uv:

    uv sync
  3. Verify installation:

    uv run patent-mcp-server

    Should output:

    INFO     Starting USPTO Patent MCP server with stdio transport

API Key Setup

USPTO ODP API Key (Required for most tools)

To use the api.uspto.gov tools (ODP, PTAB), you need an Open Data Portal API key. Without it, these endpoints return 403 Forbidden. The Patent Litigation API is not offered on ODP and does not require an API key.

  1. Create a USPTO.gov account at data.uspto.gov (requires ID.me verification)

  2. Once signed in, visit "My ODP" in the site navigation to get your API key

  3. See the Getting Started guide for detailed instructions

  4. Complete your data.uspto.gov customer profile (job title, organization, intended use). ODP deactivates keys whose profile is incomplete, and a key that stops working with 401/403 usually means this.

  5. Create a .env file in the patent_mcp_server directory:

    USPTO_API_KEY=your_actual_key_here

    Note: The PPUBS patent tools, trademark search (tm_* search tools), and trademark assignment search work without any API key.

TSDR API Key (Trademark status/document tools)

The TSDR tools (tsdr_*) require a TSDR-specific API key sent as the USPTO-API-KEY header. The ODP key does not work for TSDR — it passes the gateway's auth check, but every request then fails with BACKEND RESPONSE STATUS: 404.

  1. Sign in to the USPTO API Key Manager with a free MyUSPTO account

  2. Select the TSDR API product and click "Request API key" (the key is emailed and stored under your account)

  3. Add it to your .env:

    TSDR_API_KEY=your_tsdr_key_here

TSDR rate limits (peak hours 5am-10pm ET): 60 requests/minute general, 4 requests/minute for PDF document bundles (120/12 off-peak). Use tsdr_list_trademark_documents (metadata only, not rate-limited like PDFs) before downloading bundles.

Trademark search and AWS WAF (no key needed)

tm_search_trademarks / tm_get_trademark use the internal API behind tmsearch.uspto.gov, which sits behind AWS WAF. It currently answers plain requests, but if USPTO tightens the WAF and searches start failing with 403/202 errors, copy the aws-waf-token cookie from a browser session on tmsearch.uspto.gov (valid ~4 days) and set:

TMSEARCH_WAF_TOKEN=your_cookie_value_here

Configuration

The server can be configured using environment variables in your .env file. All settings are optional with sensible defaults:

# API Keys
USPTO_API_KEY=your_key_here      # ODP/PTAB tools
TSDR_API_KEY=your_tsdr_key_here  # TSDR trademark tools (separate key — see above)
TMSEARCH_WAF_TOKEN=...           # Optional - only if trademark search hits the WAF

# Tool registration
ENABLE_LEGACY_TOOLS=false  # Also register the 23 tools for shut-down APIs (they return API_UNAVAILABLE)

# Logging
LOG_LEVEL=INFO  # Options: DEBUG, INFO, WARNING, ERROR, CRITICAL

# MCP Transport (see "Remote hosting over HTTP" below)
MCP_TRANSPORT=stdio    # stdio (default) or streamable-http
MCP_HOST=127.0.0.1     # Bind address when serving over HTTP
MCP_PORT=8000          # Port when serving over HTTP
MCP_PATH=/mcp          # URL path of the MCP endpoint
MCP_STATELESS=true     # Keep no per-client state between HTTP requests
MCP_JSON_RESPONSE=false # Reply with plain JSON instead of an SSE stream

# HTTP Settings
REQUEST_TIMEOUT=30.0  # Request timeout in seconds
MAX_RETRIES=3         # Maximum number of retry attempts
RETRY_MIN_WAIT=2      # Minimum wait time between retries (seconds)
RETRY_MAX_WAIT=10     # Maximum wait time between retries (seconds)

# Session Management
SESSION_EXPIRY_MINUTES=30  # How long to cache ppubs sessions
ENABLE_CACHING=true        # Enable/disable session caching

# API Endpoints (usually don't need to change)
PPUBS_BASE_URL=https://ppubs.uspto.gov
API_BASE_URL=https://api.uspto.gov          # ODP API endpoint (NOT data.uspto.gov)
TSDR_BASE_URL=https://tsdrapi.uspto.gov/ts/cd
TMSEARCH_BASE_URL=https://tmsearch.uspto.gov
TM_ASSIGNMENT_BASE_URL=https://assignmentcenter.uspto.gov
CPC_SCHEME_BASE_URL=https://www.uspto.gov/web/patents/classification/cpc/html

Claude Desktop Configuration

To integrate this MCP server with Claude Desktop:

  1. Update your Claude Desktop configuration file (claude_desktop_config.json):

    {
      "mcpServers": {
        "patents": {
          "command": "uv",
          "args": [
            "--directory",
            "/Users/username/patent_mcp_server",
            "run",
            "patent-mcp-server"
          ]
        }
      }
    }

    You can find claude_desktop_config.json on a Mac by opening the Claude Desktop app, opening Settings (from the Claude menu or by Command + ' on the keyboard), clicking "Developer" in the sidebar, and "Edit Config."

  2. Replace /Users/username/patent_mcp_server with the actual path to your patent_mcp_server directory.

When integrated with Claude Desktop, the server will be automatically started when needed and doesn't need to be run separately.

Claude Code Configuration

To integrate this MCP server with Claude Code for a particular project, from the project root:

claude mcp add-json patents '{"command": "uv", "args": ["--directory", "/path/to/patent_mcp_server", "run", "patent-mcp-server"]}'

If you're already running Claude Code, you'll have to /exit and restart. Then /mcp to verify that it's configured.

Remote hosting over HTTP

The server speaks stdio by default, which is what the Claude Desktop and Claude Code configurations above launch. It can instead serve the MCP endpoint over HTTP, so one deployment can back a whole team rather than every person running their own copy with their own API keys:

patent-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000

The endpoint is then at http://<host>:8000/mcp. Point an MCP client at that URL — in Claude Code:

claude mcp add --transport http patents http://your-host:8000/mcp

This endpoint has no authentication of its own, and it holds your USPTO and TSDR API keys. Anyone who can reach it can spend your USPTO rate limits. Bind to 127.0.0.1 (the default) and put an authenticating reverse proxy in front of it, or otherwise restrict network access. The server logs a warning at startup when it is bound to anything other than loopback.

Requests are stateless by default: the server keeps no per-client state between them, so it can run behind a load balancer with several replicas and no session affinity. Each worker holds its own upstream USPTO Public Search session, which it establishes on demand and refreshes when it expires.

Flag

Default

Purpose

--transport

stdio

stdio or streamable-http

--host

127.0.0.1

Bind address for HTTP

--port

8000

Port for HTTP

--path

/mcp

URL path of the MCP endpoint

--stateful / --no-stateful

off

Keep per-client session state; needs session affinity to scale

--json-response / --no-json-response

off

Reply with plain JSON instead of an SSE stream

Each flag has a matching environment variable (see Configuration above); the command line wins where both are set.

Available Tools

Utility Tools

Tool

Description

check_api_status

Check status of all USPTO APIs

get_cpc_info

CPC title at any depth (section to subgroup) with hierarchy and children; groups come live from USPTO's scheme pages

get_status_code

Look up USPTO status code meaning

get_trademark_class_info

Look up a Nice/international trademark class (1-45)

get_trademark_status_code

Look up a USPTO trademark status code meaning

Patent Public Search (ppubs.uspto.gov)

Tool

Description

ppubs_search_patents

Search granted patents (full-text, daily updates)

ppubs_search_applications

Search published patent applications

ppubs_get_full_document

Get a document by GUID; sections picks biblio, abstract, claims or description

ppubs_get_patent_by_number

Get a patent's text by number ("US 10,000,000 B2", "D845123" and "RE49123" all work), with the same sections option

ppubs_get_citing_patents

Forward citations: later granted patents that cite a patent

ppubs_download_patent_pdf

Download patent as PDF

Open Data Portal (api.uspto.gov)

Tool

Description

odp_get_application

Get basic application data

odp_search_applications

Search applications with filters

odp_get_application_metadata

Get comprehensive metadata

odp_get_continuity

Get patent family/continuity data

odp_get_assignment

Get ownership/assignment records

odp_get_adjustment

Get patent term adjustment data

odp_get_attorney

Get attorney/agent of record

odp_get_foreign_priority

Get foreign priority claims

odp_get_transactions

Get prosecution transaction history

odp_get_documents

List file wrapper documents, filtered by document code (CTNF, CTFR, NOA, REM, CLM, 892…) and direction

odp_download_document

Read one file wrapper document as plain text (format="text": office actions, remarks, claims with amendment markup) or as PDF

odp_search_office_actions

Search office actions across applications by text, document code, rejection statute, art unit and date; previews are cut at 500 characters, so read hits with odp_download_document(format="text")

get_office_action_rejections

Claims rejected, objected to or allowed in each office action, by statute (101/102/103/112/DP), with Alice/Mayo/Myriad/Bilski flags; filter by application, patent, date, art unit or case law

get_office_action_citations

References each office action cited, with the 102/103 section; cited_reference finds every application whose examiner cited a given patent or publication

odp_search_petition_decisions

Search petition decisions by text, petition type, outcome, deciding office and date, with outcome counts

odp_search_datasets

Search bulk data products

odp_get_dataset

Get dataset product details

PTAB Trial API (api.uspto.gov ODP v3.0)

Tool

Description

ptab_search_proceedings

Search IPR/PGR/CBM proceedings by patent number, party, status

ptab_get_proceeding

Get details for a specific proceeding by number

ptab_get_documents

List documents filed in a proceeding

ptab_search_decisions

Search PTAB decisions

ptab_get_decision

Get a specific decision by trial number

ptab_search_appeals

Search ex parte appeals

ptab_get_appeal

Get details for a specific appeal

TSDR - Trademark Status and Document Retrieval (tsdrapi.uspto.gov)

Tool

Description

tsdr_get_trademark_status

Get authoritative live status by serial or registration number

tsdr_list_trademark_documents

List prosecution document metadata (no rate limit, no downloads)

tsdr_download_trademark_documents

Download prosecution document bundle as PDF (4/min rate limit)

tsdr_get_trademark_image

Get the mark image (drawing) as base64

Trademark Search & Assignments

Tool

Description

tm_search_trademarks

Full-text search by mark text, owner, goods/services, class, live/dead status

tm_get_trademark

Get a trademark's search-index record by serial number

tm_search_assignments

Search recorded ownership transfers, 1955-present (Assignment Center, no key)

Note: tm_search_trademarks and tm_get_trademark use the undocumented internal API behind tmsearch.uspto.gov (the TESS replacement) — the same situation as the PPUBS patent search API. USPTO offers no official REST API for full-text trademark search. The request/response contract was verified live on 2026-06-10, but these tools may break without notice if USPTO changes the internal API. TTAB proceedings (oppositions/cancellations) have no REST API; daily TTAB XML is available as bulk datasets via odp_search_datasets.

Legacy tools (hidden unless ENABLE_LEGACY_TOOLS=true)

The 23 tools below are for APIs USPTO has shut down. They stay in the code and keep their names, but the server registers them only when ENABLE_LEGACY_TOOLS=true, because their schemas cost every client about 6k tokens per session and every call returns API_UNAVAILABLE. Each response carries a workaround naming the live tool that covers the need.

Patent Litigation API (Unavailable — not offered on ODP, issue #16)

All 4 Litigation tools return API_UNAVAILABLE. The Patent Litigation API is not listed in the ODP Swagger catalog. The OCE Patent Litigation dataset (74,000+ district court cases) is distributed as a bulk download at https://www.uspto.gov/ip-policy/economic-research/research-datasets/patent-litigation-docket-reports-data.

Tool

Workaround

search_litigation

OCE Patent Litigation bulk dataset

get_litigation_case

OCE Patent Litigation bulk dataset

get_patent_litigation

OCE Patent Litigation bulk dataset or ppubs_search_patents

get_party_litigation

OCE Patent Litigation bulk dataset

PatentsView API (Unavailable — shut down March 2026)

All 14 PatentsView tools return API_UNAVAILABLE with workaround guidance. PatentsView data has been migrated to the USPTO Open Data Portal as bulk downloadable datasets. Use ppubs_search_patents for patent search, odp_search_datasets to find bulk datasets.

Tool

Workaround

patentsview_search_patents

ppubs_search_patents

patentsview_get_patent

ppubs_get_patent_by_number

patentsview_search_assignees

ppubs_search_patents with "name".as. query

patentsview_get_assignee

odp_search_datasets (bulk data)

patentsview_search_inventors

ppubs_search_patents with "name".in. query

patentsview_get_inventor

odp_search_datasets (bulk data)

patentsview_get_claims

ppubs_get_full_document

patentsview_get_description

ppubs_get_full_document

patentsview_search_by_cpc

ppubs_search_patents with code.cpc. query

patentsview_lookup_cpc

get_cpc_info

patentsview_search_attorneys

odp_get_attorney (per-application)

patentsview_get_attorney

odp_get_attorney (per-application)

patentsview_search_by_ipc

ppubs_search_patents with IPC query

patentsview_lookup_ipc

odp_search_datasets (bulk data)

Office Action APIs (Unavailable — decommissioned early 2026)

These 2 Office Action tools return API_UNAVAILABLE; odp_search_office_actions replaces them. get_office_action_citations and get_office_action_rejections are live again on ODP (v1.8.0).

Tool

Workaround

get_office_action_text

odp_search_office_actions(app_num=...) then odp_download_document

search_office_actions

odp_search_office_actions

Enriched Citation APIs (Unavailable — decommissioned early 2026)

All 3 Enriched Citation tools return API_UNAVAILABLE. Forward citations come from ppubs_get_citing_patents; the references a patent cites are on its front page (ppubs_get_patent_by_number(sections=["biblio"])).

Tool

Workaround

get_enriched_citations

ppubs_get_citing_patents (forward) and ppubs_get_patent_by_number(sections=["biblio"]) (backward)

search_citations

ppubs_get_citing_patents

get_citation_metrics

ppubs_get_citing_patents — total is the forward-citation count

Resources and Prompts

The server also provides MCP Resources (accessible via @ mentions):

  • patents://cpc/{code} - CPC classification information at any depth (groups from USPTO's scheme pages)

  • patents://status-codes - USPTO status code definitions

  • patents://sources - Data source information

  • patents://search-syntax - Query syntax guide (patents and trademarks)

  • trademarks://classes - Nice/international trademark classes (1-45)

  • trademarks://status-codes - Trademark status code definitions

And MCP Prompts (workflow templates). Each takes optional arguments; whatever you give is placed in a Subject section ahead of the steps, so the workflow starts with your specifics instead of asking for them:

  • prior_art_search (invention, keywords, cpc_codes) - Comprehensive prior art search guide

  • patent_validity_analysis (patent_number) - Patent validity analysis workflow

  • competitor_portfolio_analysis (company, technology) - Competitor portfolio analysis

  • ptab_proceeding_research (patent_number, proceeding_number, party) - PTAB proceeding research guide

  • freedom_to_operate (product, cpc_codes) - FTO analysis workflow

  • patent_landscape (technology, cpc_codes) - Technology landscape mapping

  • trademark_clearance_search (mark, goods_services, classes) - Trademark clearance/knockout search guide

  • trademark_portfolio_review (owner) - Trademark portfolio and deadline review

  • trademark_status_monitoring (serial_numbers, mark) - Trademark status and conflict watching

Testing

The project includes comprehensive test suites:

# Run unit tests (default - skips integration tests)
uv run pytest

# Run with verbose output
uv run pytest -v

# Run integration tests (requires network access)
uv run pytest -m integration

# Run all tests including integration
uv run pytest -m ""

# Run with coverage report
uv run pytest --cov=patent_mcp_server

Integration tests save each tool's output to test/test_results/ for inspection. The directory is git-ignored: the files are rewritten on every run and nothing reads them back. Recorded responses that tests depend on belong in test/fixtures/.

The unit suite also runs in CI on every push to main and every pull request, across Python 3.10–3.13 (.github/workflows/tests.yml). Integration tests stay deselected there, so CI needs no API keys.

Development

To install development dependencies:

uv sync --dev

Publishing to PyPI

Releases go out through the Publish to PyPI GitHub Actions workflow (.github/workflows/publish.yml), which uploads with PyPI trusted publishing, so no API token is stored anywhere. After the version bump (pyproject.toml and the USER_AGENT in config.py) is merged to main, run the workflow from the Actions tab. It refuses a version PyPI already has, runs the tests, builds, publishes, and creates the vX.Y.Z tag and GitHub release.

To build locally:

rm -rf dist/ && uv run python -m build

Contributing

Issues and PRs welcome. See CONTRIBUTING.md for the contribution guide, and AGENTS.md for guidance specific to AI agents. Use the bug report or feature request templates when filing an issue — they prompt for the tool call, the constructed request URL/body, and the raw API response, which is usually enough to land a fix in one turn.

Version History

v1.8.3 (Current)

  • Office action paging skips nothing after truncation: get_office_action_rejections pages by dataset rows but returns office actions, so when the token budget dropped actions, metadata.next_offset still pointed past their rows and the next page never showed them. It now points at the first row of the first dropped action, and rows_returned counts only the rows kept. get_office_action_citations had the same gap row for row and gets the same fix.

v1.8.2

  • Keep truncated search results reachable: when the token budget removes records from the final page, has_more remains true. Continue at offset + count to retrieve the omitted records. Pages shortened only by stripping heavy fields keep their original pagination state.

v1.8.1

  • Releases publish from GitHub Actions: the new Publish to PyPI workflow uploads through PyPI trusted publishing, so no API token is stored anywhere, and it tags each release and creates its GitHub release. This is the first version it published

  • Docs: the legacy tool count now reads 23 everywhere (it said 25 in a few places after the two office action dataset tools went live in v1.8.0)

v1.8.0

  • get_office_action_rejections and get_office_action_citations are live again, on ODP's claim-level datasets (/api/v1/patent/oa/oa_{rejections,citations}/v2/records) instead of the decommissioned developer.uspto.gov paths. Rejections come grouped by office action: the statutes it applies (101, 102, 103, 112, double patenting), the Alice, Mayo, Myriad and Bilski flags, and which claims were rejected, objected to or allowed. Filter by application or patent number, mail date, date range, statute, case law, document code and art unit, so case_law="alice", art_unit="3689" finds an art unit's Alice rejections. Citations list each reference an action cited and the section it was applied under; cited_reference runs the lookup in reverse

  • Both tools return each action's document_id, which odp_download_document(format="text") reads

  • Coverage: rejections from 2012 on (93M rows), about a week behind the mail date

  • Tool count: 42 registered by default (65 with ENABLE_LEGACY_TOOLS)

  • Verified live 2026-10-15

v1.7.0

  • Full text of file-wrapper papers: odp_download_document takes format="text" and returns a paper's body as plain text from the XML USPTO publishes beside the PDF, so an office action (typically 10–20k characters) no longer has to be read as a base64 PDF. It covers office actions, notices of allowance, petition decisions, and applicant papers such as remarks (REM), claims (CLM) and IDS forms; amended claims keep their markup as ~~deleted~~ and ++inserted++. Long papers come in 24k-character pages split at paragraph breaks (text_offset / next_offset). A document without XML returns NO_TEXT_AVAILABLE, and the PDF remains the default format

  • Parsed with the standard library; XML that declares entities is refused

  • Verified live 2026-10-14 on CTNF, CTFR, NOA, REM, CLM, IDS, PET.PCT, PETDEC and SPEC papers from 2011 to 2026

v1.6.0

  • New odp_search_office_actions searches ODP's Office Action dataset (19.9M actions mailed since mid-2007) by full text, document code, rejection statute (101/102/103/112/double patenting), art unit, date and patent number. Every response carries facet counts by document code and statute for the whole match set, so limit=1 answers counting questions. The API returns only the first 500 characters of each action; a hit's document_id is the file-wrapper documentIdentifier, so odp_download_document reads the rest

  • New odp_search_petition_decisions searches 1.1M petition decisions (1991 on) by text, petition type code or words, outcome, deciding office, technology center, date and final-agency-action flag, with outcome, office and type facets. Query matches in the excerpt are marked «like this»; include_full_text adds each decision's full OCR text

  • The get_office_action_text and search_office_actions legacy stubs now point to the new tool; check_api_status lists both datasets as active

  • 401/403 from these endpoints carry a hint about ODP's customer-profile requirement

  • Tool count: 40 registered by default (65 with ENABLE_LEGACY_TOOLS)

  • Verified live 2026-10-14

v1.5.0

  • CPC titles below subclass level: get_cpc_info (and patents://cpc/{code}) used a bundled table that stopped at the class level, so G06N 3/08 came back as "Computing; Calculating; Counting". Subclasses, main groups and subgroups now come from USPTO's published CPC scheme page for the subclass (www.uspto.gov/web/patents/classification/cpc/html/cpc-G06N.html; no key), fetched once a day per subclass: G06N 3/08 → "Learning methods", with the hierarchy G06N › 3/00 › 3/02 › 3/08 and the subgroups beneath it. Accepts every form the other tools print (G06N3/08, G06N 3/08, H04B7/0417 20130101). A code the scheme does not contain returns NOT_FOUND with the subclass's main groups; if the page cannot be fetched, the static section and class titles come back with a scheme_error

  • Prompt arguments: all nine workflow prompts take optional arguments (patent number, company, mark, CPC codes, …). Whatever you give appears in a Subject section ahead of the steps; with no arguments the prompts read as before

  • New CPC_SCHEME_BASE_URL setting; new cpc_scheme entry in check_api_status

  • Verified live 2026-09-26: G06N 3/08, G06N, A61K, H04B 7/0417, and an unknown subclass and group

v1.4.0

  • httpx → httpx2 for the nine USPTO clients and the logging transport. httpx2 is the successor from the same author (now under the pydantic organization) and is what mcp 2 already depends on; httpx 0.28.1 (December 2024) and httpcore 1.0.9 (April 2025) have stopped moving. The API is the same for everything this code uses (AsyncClient, AsyncHTTPTransport, Cookies, build_request/send(stream=True), the exception classes), so the change is a rename across 20 files; httpx and httpcore leave the dependency tree entirely. The PPUBS session handling, PDF print job, TSDR XML document list, tmsearch, Assignment Center v3 and the ODP document download redirect were each re-verified live on 2026-09-26 (whole suite, nothing deselected)

v1.3.0

  • MCP Python SDK 2.x: the server now builds on mcp>=2,<3 (MCPServer, the renamed FastMCP), which lifts the mcp<2 pin v1.2.1 added. Tool names, arguments and results are unchanged; the --host/--port/--path/--stateful/--json-response flags and MCP_* variables keep their meaning. Under the hood the transport settings move from the server constructor to run_streamable_http_async(), the protocol tests use mcp 2's in-memory Client, and the dependency drops the [cli] extra (empty in 2.x)

  • Structured output off: mcp 2 sends every dict result twice by default, as JSON text and again as structured_content, against an output schema of "any object" — measured at 2.0x wire size on documents and searches. Tools register with structured_output=False, so results travel once, as before

  • Pinned click>=8.3.3 (PYSEC-2026-2132; a transitive dependency via uvicorn that predates this release) so pip-audit is clean on the new tree

  • Verified 2026-09-26: unit suite on mcp 2.2.0; the live suite (unit plus integration, nothing deselected); a clean uvx install from the built wheel; stdio and streamable-http smoke tests through mcp 2's own client

v1.2.1

  • Fixed fresh installs: mcp[cli]>=1.27 resolved to mcp 2.x, which renamed mcp.server.fastmcp to mcp.server.mcpserver, so uvx patent-mcp-server and pip install patent-mcp-server crashed on import (ModuleNotFoundError: No module named 'mcp.server.fastmcp'). mcp 2.0.0 shipped on 2026-07-28, so v1.1.1 and v1.2.0 were both affected; the checked-in uv.lock (mcp 1.28.1) hid it from local runs and CI. The dependency is now mcp[cli]>=1.27,<2. Migrating to the mcp 2 API is a separate piece of work

v1.2.0

  • Fixed patent-number parsing: "US 9,876,543 B2" was read as 98765432 (the kind code folded into the number) and "D845123" as 845123, a 1907 utility patent. Numbers now keep their D/RE/PP prefix and lose separators, a leading "US" and the kind code. The lookup also dropped a dead patentNumber:"…" query that returned nothing and cost ~3 s per call

  • sections on ppubs_get_full_document and ppubs_get_patent_by_number: choose biblio, abstract, claims, description. A whole document is ~24k tokens; ["biblio", "claims"] is ~6k. Empty and search-highlight fields are dropped from every document

  • Smaller search results: each PPUBS hit carried two 7 KB references-cited lists; three hits are now 5k characters instead of 41k. ppubs_search_* default to limit=20 (the truncation step cut larger responses to 20 anyway)

  • New odp_download_document fetches a file-wrapper document (office action, response, notice of allowance…) as PDF, following ODP's signed 30-second redirect; documents over 4 MB are refused. odp_get_documents gains document_code and direction filters, paging, and a per-code count of the whole wrapper

  • New ppubs_get_citing_patents: forward citations via the .urpn. field of granted patents; total is the citation count

  • Legacy tools hidden by default: the 25 tools for shut-down APIs made up 39% of the schema text sent to every client (~6k tokens). Set ENABLE_LEGACY_TOOLS=true to register them; the functions, names and workaround messages are unchanged

  • Read-only annotations on every tool, so clients that honor them need not confirm each call

  • The competitor-portfolio, freedom-to-operate and patent-landscape prompts, the patentsview_* workaround messages and this README still taught the slash-prefix search syntax that stopped working in August (AN/, IN/, CPC/); all now use .as., .in., .cpc. and @pd

  • Removed test/test_patents.py: two script-style live checks that logged errors instead of asserting, so they always passed while calling USPTO and rewriting json/ and pdfs/ on every default pytest run, including CI. The default suite now makes no network calls

  • Fixed tm_search_assignments: Assignment Center moved its search API from /ipas/search/api/v2/ to /v3/, and CloudFront now refuses POST on the old path with a 403 HTML page. Same request body and response envelope; only the path changed

  • 429 handling in the ODP and PTAB clients: a rate-limited call now waits (Retry-After, else exponential backoff) and retries up to MAX_RETRIES instead of returning the 429 to the caller. api.uspto.gov limits per key, so a burst of tool calls tripped it

  • Integration tests: test/test_tools.py and test/test_tools_pytest.py were duplicates; the pytest one survives under the shorter name, minus eight skipped PatentsView tests, with its patentNumber:"…" queries and numFound assertions (neither matched the live API or the tool envelope any more) fixed, and with live tests for sections, prefixed numbers, ppubs_get_citing_patents, the odp_get_documents filter and odp_download_document. uv run pytest -m "" runs the whole suite, unit and live, and passes

  • Live-verified 2026-09-26: .pn. with D/RE prefixes, .urpn., the ODP document listing and download redirect, Assignment Center v3

  • Tool count: 38 registered by default (63 with ENABLE_LEGACY_TOOLS)

v1.1.1

  • Fixed ppubs_download_patent_pdf: USPTO moved the PDF download endpoint — the old /api/internal/print/save/{pdfName} path now returns 404; the client uses the live /api/print/save/{pdfName} endpoint (verified live 2026-08-05 with a real search, document fetch, and PDF download)

  • Corrected PPUBS search syntax guidance: the slash-prefix field qualifiers (TTL/, IN/, AN/, CPC/) no longer work on the live API — they silently return 0 results, and TTL/"phrase" returns a server 500. Search tool docstrings, the prior-art prompt, and the patents://search-syntax guide now teach the working dotted-suffix forms (.ti., .ab., .clm., .spec., .in., .as., .pn., .cpc., @pd/@ad date ranges), each verified live

  • Both breakages were USPTO-side drift predating v1.1.0 (confirmed by running the same live test against v1.0.0-era code)

v1.1.0

  • Remote hosting over HTTP: new --transport streamable-http mode serves the MCP endpoint over the network, so one deployment can back a whole team instead of every user running a local copy. stdio remains the default, so existing Claude Desktop and Claude Code configurations are unchanged. New flags --host, --port, --path, --stateful, --json-response, each with a matching MCP_* environment variable. See "Remote hosting over HTTP" for the security caveat — the endpoint holds your API keys and does not authenticate callers

  • Stateless by default: HTTP requests carry no per-client state, so the server can run behind a load balancer with several replicas and no session affinity

  • Fixed a session race in the Public Search client (affects stdio users too): concurrent tool calls each reset the shared cookie jar and raced to swap the access token, so requests already in flight could be signed with a half-replaced session. Session setup is now serialized, a 403 refresh is skipped when another call has already replaced the token, and the token travels per request instead of living on the shared client's default headers

  • Fixed shutdown: closing the nine HTTP clients no longer happens in an atexit hook that spun up a fresh event loop; it now runs in the loop the clients were opened on. Deliberately not a FastMCP lifespan — in stateless HTTP mode that runs once per request, which would close the clients after the first tool call

  • Raised the MCP SDK floor to >=1.27 (was >=1.3.0, which allowed installs to resolve an SDK without streamable HTTP)

  • Added MCP protocol-layer tests: the suite previously called tool functions directly and never exercised schema generation, resource/prompt registration, or serialization. 19 new tests (378 total, up from 359)

v1.0.0

  • Trademark support: 9 new trademark tools across three new clients, all verified against the live USPTO services on 2026-06-10

    • TSDR (tsdr_get_trademark_status, tsdr_list_trademark_documents, tsdr_download_trademark_documents, tsdr_get_trademark_image) — official trademark status/document API. Requires a TSDR-specific key (the ODP key does not work); error responses detect the wrong-key signature and explain how to get the right one. Document bundles above 4 MB are rejected with filter guidance (full wrappers can exceed 10 MB)

    • Trademark search (tm_search_trademarks, tm_get_trademark) — full-text search by mark text, owner, goods/services, and Nice class via the internal Elasticsearch API behind tmsearch.uspto.gov (no official REST API exists). Verified live; handles AWS WAF rejections with TMSEARCH_WAF_TOKEN support

    • Trademark assignments (tm_search_assignments) — USPTO Assignment Center public API (assignmentcenter.uspto.gov, no key required), searchable by serial/registration number, assignee, assignor, and reel/frame. Replaced the legacy assignment-api.uspto.gov XML API decommissioned June 5, 2026

  • New reference tools and resources: get_trademark_class_info, get_trademark_status_code, trademarks://classes, trademarks://status-codes (all 45 Nice classes, common trademark status codes)

  • 3 new workflow prompts: trademark_clearance_search, trademark_portfolio_review, trademark_status_monitoring

  • Fixed ppubs_download_patent_pdf (called download_image with the wrong signature, raising TypeError)

  • Rewrote patent workflow prompts to reference live tools (the old prompts still pointed at decommissioned PatentsView/Office Action/citation tools)

  • New env vars: TSDR_API_KEY, TMSEARCH_WAF_TOKEN, TSDR_BASE_URL, TMSEARCH_BASE_URL, TM_ASSIGNMENT_BASE_URL

  • Tool count: 61 registered (36 active, 25 unavailable)

v0.9.5

  • Re-enable 7 PTAB tools on USPTO ODP v3.0: ptab_search_proceedings, ptab_get_proceeding, ptab_get_documents, ptab_search_decisions, ptab_get_decision, ptab_search_appeals, ptab_get_appeal (issue #23). PTAB data relocated to ODP /api/v1/patent/trials/* and /api/v1/patent/appeals/* (paths not in the ODP Swagger UI); the standalone-API decommission (issue #16) was correct for the Patent Litigation API, but PTAB moved rather than disappeared.

  • Active tool count: 27 (up from 20); unavailable: 25 (down from 32); total registered remains 52

v0.9.4

  • Fix ppubs_search_patents / ppubs_search_applications query semantics (issue #21): default operator changed from OR to AND, so multi-word queries like machine learning no longer match the entire corpus and collapse into the latest-grants fallback under date_publ desc sort.

  • Fix template-mutation bug in PPUBS client (search_query.copy() → copy.deepcopy(...)), eliminating a concurrency hazard between parallel calls.

  • Fix odp_search_applications filters being silently ignored upstream (issue #21): switched from GET query-string params to POST with a Lucene-style q body. assignee_name, inventor_name, application_number, patent_number, and filing-date ranges are now properly AND-combined into the search. Tool now returns MISSING_FILTER rather than dumping the full 12.8M-record corpus when called with no filters.

  • Updated ppubs_search_patents / ppubs_search_applications / odp_search_applications docstrings to reflect the corrected semantics and document Lucene query support on ODP.

  • Added CONTRIBUTING.md, AGENTS.md, bug-report + feature-request issue templates, and a PR template.

v0.9.0

  • Handle PTAB Trial API and Patent Litigation API unavailability on ODP (issue #16)

  • All 7 ptab_* tools and 4 litigation tools now return API_UNAVAILABLE with workaround guidance pointing to PPUBS tools and USPTO bulk datasets

  • Active tool count: 20 (down from 31); unavailable: 32 (up from 21); total registered remains 52

  • Added unit tests for all 11 newly-unavailable tools and extended the shared error-structure parametrization

  • Updated check_api_status, resources.py data sources, client docstrings, and README to reflect the shutdown

v0.8.0

  • Handle decommissioned PatentsView API (shut down March 20, 2026)

  • All 14 patentsview_* tools return API_UNAVAILABLE with workaround guidance

  • Fixed circular references in office_actions resources that pointed to unavailable PatentsView tools

  • Updated API Sources table, configuration, and documentation

v0.7.0

  • Handle decommissioned Office Action and Enriched Citation APIs (developer.uspto.gov)

  • All 7 affected tools return API_UNAVAILABLE with workaround guidance

  • Added test/unit/test_unavailable_tools.py for decommissioned tool testing

  • Code cleanup: removed dead code, improved docstrings

v0.6.2

  • Updated API key registration instructions: keys are now obtained from data.uspto.gov ("My ODP")

  • Clarified that api.uspto.gov is the correct API endpoint (not data.uspto.gov which is the web portal)

  • Noted PTAB API v3 migration to ODP and Office Action API migration (early 2026)

v0.6.1

  • Added PatentsView attorney search tools (patentsview_search_attorneys, patentsview_get_attorney)

  • Added PatentsView IPC classification tools (patentsview_lookup_ipc, patentsview_search_by_ipc)

  • Fixed bug in search_publications method (pagination options not being passed)

v0.6.0

  • PyPI release preparation

v0.5.0

  • Focused on USPTO-only data sources

  • Renamed ODP tools with odp_ prefix for clarity

  • Improved function signatures (using query instead of q)

v0.3.0

  • Added 33 new tools (PTAB, PatentsView, Office Actions, Citations, Litigation)

  • Rate limiting support for PatentsView API

  • Comprehensive async client architecture

v0.2.2

  • Centralized configuration with environment variables

  • Standardized error handling

  • Input validation with Pydantic

  • Retry logic with exponential backoff

  • Session caching for PPUBS

License

MIT

Available Tools

42 tools
check_api_statusA
Read-onlyIdempotent

Check status and availability of all patent and trademark data sources.

USE THIS TOOL WHEN: You encounter errors or want to verify which APIs
are available and properly configured before starting research.

Returns status of each data source including:
- Configuration status (API keys, credentials)
- Connection availability
- Rate limit information where available

Inputs: no named parameters.

get_cpc_infoA
Read-onlyIdempotent

Look up a CPC (Cooperative Patent Classification) symbol at any depth.

USE THIS TOOL WHEN: You need the title of a CPC code — section (G),
class (G06), subclass (G06N), main group (G06N 3/00) or subgroup
(G06N 3/08) — its place in the hierarchy, or the groups beneath it,
whether reading the codes on a patent or choosing codes for a
`.cpc.` search.

Sections and classes come from a bundled table. Subclasses and groups
come from USPTO's published CPC scheme page for the subclass (one
fetch per subclass per day, no key), so titles track the current CPC
version.

Args:
    cpc_code: Any CPC symbol form: "G06N3/08", "G06N 3/08",
           "H04B7/0417 20130101" (as PPUBS prints it), "G06N", "G06",
           "G".

Returns:
    Section: title, description and its classes. Class: section and
    class titles. Subclass or group: `title`, `level`, `hierarchy`
    from the subclass down to the code, direct `children`, and the
    source page. If the scheme page cannot be fetched, the static
    section and class titles come back with a `scheme_error`.

Inputs: cpc_code (required).

get_office_action_citationsA
Read-onlyIdempotent

Get the prior art examiners cited in office actions.

USE THIS TOOL WHEN: You need the references an examiner cited against
an application, and under which statute (102 or 103); or, in reverse,
which applications' office actions cited a given patent or publication
(cited_reference="US 2013/0120945 A1"). For citations on an issued
patent's front page, ppubs_get_patent_by_number(sections=["biblio"])
is cheaper; for later patents citing it, ppubs_get_citing_patents.

Coverage: office actions from about 2012 on; rows appear about a week
after mailing. Rows carry no mail date, so mail_date (with an
application or patent number) finds that day's actions in the
rejection dataset first.

Args:
    application_number: Application number without slashes (e.g. "18402543")
    mail_date: Mail date of one action, YYYY-MM-DD (needs
        application_number or patent_number)
    patent_number: Patent number; resolved to its application first
    document_id: File-wrapper documentIdentifier of one action
    cited_reference: A cited US patent or publication number, with or
        without "US", separators or kind code
    legal_section: Comma-separated sections the reference was applied
        under: 102, 103
    examiner_cited: True for references the examiner cited
    art_unit: Group art unit (e.g. "1798")
    tech_center: Technology center (e.g. "1700")
    query: Extra Solr clause, AND-ed with the filters
    offset: Row offset (default: 0)
    limit: Rows to read (default: 50, at most 200)

Returns:
    Citations with app_num, document_id, reference (as written),
    reference_number (digits, when USPTO parsed them), legal_section,
    action, examiner_cited, applicant_cited, relied_on_in_action,
    art_unit and tech_center.

Inputs: limit, query, offset, art_unit, +8 more.

get_office_action_rejectionsA
Read-onlyIdempotent

Get claim-level rejection data from office actions.

USE THIS TOOL WHEN: You need which claims an examiner rejected, objected
to or allowed in each office action, and under which statute (101, 102,
103, 112, double patenting); or claim-level 101 analytics across
applications, such as actions citing Alice or Mayo in an art unit
(case_law="alice", art_unit="3689"). For the action's text, search with
odp_search_office_actions and read it with odp_download_document.

Results come grouped by office action. statutes and case_law describe
the whole action; claims sums up the claim numbers by what happened to
them; claim_groups keeps the dataset's rows (each with action,
legal_section, form paragraph and claims). The rows are extracted by
machine from the action's text, so treat them as a guide and read the
action for anything that matters.

Coverage: actions mailed from 2012 on (93M rows), appearing about a
week after mailing. Pagination counts rows, not actions; an action can
straddle two pages. Continue from metadata.next_offset, not offset +
count: when the token budget drops actions, next_offset points at the
first row of the first one dropped.

Args:
    application_number: Application number without slashes (e.g. "18402543")
    mail_date: Mail date of one action, YYYY-MM-DD
    patent_number: Patent number; resolved to its application first
    document_id: File-wrapper documentIdentifier of one action
    statute: Comma-separated statutes, all of which the action must
        apply: 101, 102, 103, 112, DP (double patenting)
    case_law: Comma-separated cases, all of which the action must cite:
        alice, mayo, myriad, bilski
    document_code: Comma-separated codes, e.g. CTNF (non-final), CTFR (final)
    art_unit: Group art unit (e.g. "3689")
    date_from: Earliest mail date, YYYY-MM-DD
    date_to: Latest mail date, YYYY-MM-DD
    query: Extra Solr clause, AND-ed with the filters
        (e.g. nationalClass:"705")
    offset: Row offset (default: 0)
    limit: Rows to read (default: 50, at most 200)

Returns:
    Office actions with document_id, app_num, document_code, mail_date,
    art_unit, statutes, case_law, claims and claim_groups. total counts
    rows; metadata.next_offset continues the scan.

Inputs: limit, query, offset, date_to, +9 more.

get_status_codeA
Read-onlyIdempotent

Look up USPTO application status code meaning.

USE THIS TOOL WHEN: You encounter a status code in application data
and need to understand what examination stage it represents.

Args:
    code: Status code number (e.g., "30" for "Docketed New Case")

Returns:
    Status code description and examination stage.

Inputs: code (required).

get_trademark_class_infoA
Read-onlyIdempotent

Look up a Nice/international trademark class (1-45).

USE THIS TOOL WHEN: You need to know what goods (classes 1-34) or
services (classes 35-45) a trademark class covers, or pick the right
classes for a clearance search.

Args:
    class_number: International class number (e.g., "9" for computer
        software, "25" for clothing, "42" for software services)

Returns:
    Class title, type (goods/services), and description.

Inputs: class_number (required).

get_trademark_status_codeA
Read-onlyIdempotent

Look up a USPTO trademark status code meaning.

USE THIS TOOL WHEN: Trademark data contains a numeric status code you
need to interpret (e.g., "700" = Registered, "686" = Published for
opposition).

Args:
    code: Trademark status code (e.g., "700")

Returns:
    Status code description and prosecution stage.

Inputs: code (required).

odp_download_documentA
Read-onlyIdempotent

Read one file-wrapper document, as plain text or as a PDF.

USE THIS TOOL WHEN: odp_get_documents or odp_search_office_actions
gave you a document identifier and you need to read the office
action, applicant's remarks (REM), claims (CLM), notice of allowance,
petition decision or other paper itself.

Prefer format="text": it returns the paper's body as plain text (an
office action is typically 10-20k characters) from the XML USPTO
publishes with the document. Claim amendments keep their markup,
deletions as ~~text~~ and insertions as ++text++. Applicant papers
are OCR text and can carry OCR errors. Documents listed with an
"XML" format have text; others (older papers, drawings) return
NO_TEXT_AVAILABLE, and format="pdf" still works for them.

Args:
    app_num: Application number without slashes (e.g., "16123456")
    document_id: documentIdentifier from odp_get_documents, or
           document_id from odp_search_office_actions
           (e.g., "K87AK41FRXEAPX5")
    format: "text" (plain text) or "pdf" (base64 PDF, the default)
    text_offset: With format="text", the character to start from.
           Long papers come back in 24k-character pages; pass the
           previous response's next_offset to continue.

Returns:
    format="text": {"success": True, "text", "total_chars",
    "text_offset", "next_offset" (None when done), "source_file"}.
    format="pdf": {"success": True, "filename", "content_type",
    "size_bytes", "content"} with the PDF as base64. Documents over
    4 MB are refused with RESPONSE_TOO_LARGE. Requires USPTO_API_KEY.

Inputs: app_num (required), document_id (required), format, text_offset.

odp_get_adjustmentA
Read-onlyIdempotent

Get patent term adjustment (PTA) data.

USE THIS TOOL WHEN: You need to calculate the actual expiration date
of a patent accounting for USPTO delays.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Inputs: app_num (required).

odp_get_applicationA
Read-onlyIdempotent

Get patent application data from USPTO Open Data Portal.

USE THIS TOOL WHEN: You need prosecution/file wrapper data for an
application including status, dates, and basic metadata.

Args:
    app_num: Application number without slashes or commas (e.g., "14412875")

Returns:
    Application data including filing date, status, and basic info.

Inputs: app_num (required).

odp_get_application_metadataA
Read-onlyIdempotent

Get detailed metadata for a patent application.

USE THIS TOOL WHEN: You need comprehensive application metadata
including examiner info, art unit, and detailed status.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Inputs: app_num (required).

odp_get_assignmentA
Read-onlyIdempotent

Get patent assignment/ownership records.

USE THIS TOOL WHEN: You need to know current and historical owners
of a patent or application.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Inputs: app_num (required).

odp_get_attorneyB
Read-onlyIdempotent

Get attorney/agent of record for an application.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Inputs: app_num (required).

odp_get_continuityA
Read-onlyIdempotent

Get patent family/continuity data (parent and child applications).

USE THIS TOOL WHEN: You need to understand the patent family tree -
parent applications, continuations, divisionals, and CIPs.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Returns:
    Continuity data showing parent/child relationships and priority claims.

Inputs: app_num (required).

odp_get_datasetB
Read-onlyIdempotent

Get details of a specific bulk dataset product.

Args:
    product_id: Dataset product identifier

Inputs: product_id (required).

odp_get_documentsA
Read-onlyIdempotent

List the documents in an application's file wrapper (prosecution history).

USE THIS TOOL WHEN: You need to find office actions, responses,
notices of allowance, claims, IDS forms or examiner citations for an
application, then read one with odp_download_document.

Args:
    app_num: Application number without slashes (e.g., "14412875")
    document_code: Comma-separated USPTO document codes to keep. Common
           ones: CTNF (non-final rejection), CTFR (final rejection),
           NOA (notice of allowance), REM (applicant remarks/arguments),
           CLM (claims), SPEC (specification), IDS and 1449 (applicant
           citations), 892 (examiner citations), ADS, N417 (EFS receipt).
           `metadata.code_counts` in any response lists every code in
           the wrapper.
    direction: "INCOMING" (from applicant), "OUTGOING" (from USPTO) or
           "INTERNAL" (examiner search notes etc.)
    offset: Starting position within the filtered list (default: 0)
    limit: Max documents to return (default: 50)

Returns:
    Documents newest first, each with documentIdentifier (pass it to
    odp_download_document), documentCode, description, officialDate,
    directionCategory, page count and available formats.

Inputs: app_num (required), limit, offset, direction, +1 more.

odp_get_foreign_priorityA
Read-onlyIdempotent

Get foreign priority claims for an application.

USE THIS TOOL WHEN: You need to find priority claims to foreign
applications that may affect the effective filing date.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Inputs: app_num (required).

odp_get_transactionsA
Read-onlyIdempotent

Get prosecution transaction history for an application.

USE THIS TOOL WHEN: You need the complete timeline of prosecution
events including office actions, responses, and fee payments.

Args:
    app_num: Application number without slashes (e.g., "14412875")

Inputs: app_num (required).

odp_search_applicationsA
Read-onlyIdempotent

Search patent applications in USPTO Open Data Portal.

USE THIS TOOL WHEN: You need to search applications with filtering
by applicant metadata, dates, or other criteria not available in PPUBS.

Supports both free-text queries and structured multi-field filtering.
Typed filters are AND-ed together; pass a Lucene-style string in
`query` for OR or more complex expressions.

Args:
    query: Free-text or Lucene-style query (e.g. 'neural network',
           'applicationMetaData.firstInventorName:Smith OR
           applicationMetaData.firstInventorName:Jones')
    application_number: Filter by application number (exact match)
    patent_number: Filter by patent number (exact match)
    inventor_name: Filter by inventor name (matches first inventor)
    assignee_name: Filter by applicant/assignee name (matches first applicant)
    filing_date_from: Filing date range start (YYYY-MM-DD)
    filing_date_to: Filing date range end (YYYY-MM-DD)
    offset: Starting position (default: 0)
    limit: Max results (default: 25)

Returns:
    Normalized response with matching applications.

Inputs: limit, query, offset, assignee_name, +5 more.

odp_search_datasetsA
Read-onlyIdempotent

Search USPTO bulk data products/datasets.

USE THIS TOOL WHEN: You need to find bulk download datasets
available from USPTO for large-scale analysis.

Args:
    query: Search query for dataset names/descriptions
    offset: Starting position (default: 0)
    limit: Max results (default: 25)

Inputs: limit, query, offset.

odp_search_office_actionsA
Read-onlyIdempotent

Search office actions across all applications by what the examiner wrote.

USE THIS TOOL WHEN: You need to find office actions across many
applications by their text ("means-plus-function", "Alice",
"inherent anticipation"), by statute (101/102/103/112), by art unit
or by date, or to count them. metadata.facets gives document-code and
rejection-type counts for the whole match set, so limit=1 answers
"how many 101 rejections did art unit 3689 issue in 2026" in one call.
For one application's history, odp_get_documents is cheaper.

IMPORTANT: text_preview holds only the first 500 characters. The API
searches the full text but returns no more. To read a hit, pass its
app_num and document_id to odp_download_document(format="text").

Coverage: office actions mailed from mid-2007 on (19.9M records).
Typed filters are AND-ed; pass a Lucene string in `query` for OR.

Args:
    query: Lucene query; bare words search everything, or name a field
           such as officeActionText:"printed matter"
    app_num: Application number without slashes (e.g. "18402543")
    patent_number: Patent number; resolved to its application first
    document_code: Comma-separated codes: CTNF (non-final rejection),
           CTFR (final rejection), NOA (allowance), CTRS (restriction),
           CTAV (advisory), APEA (examiner's answer), PETDEC
    rejection_type: Comma-separated statutes, all of which must apply:
           101, 102, 103, 112, DoublePatent, Other
    art_unit: Group art unit (e.g. "3689")
    date_from: Earliest mail (submission) date, YYYY-MM-DD
    date_to: Latest mail (submission) date, YYYY-MM-DD
    record_id: officeActionRecordIdentifier from an earlier result
    sort: "newest" (default) or "oldest" by mail date
    offset: Starting position (default: 0)
    limit: Max results (default: 25, at most 100)

Returns:
    Office actions with record_id, app_num, document_code, description,
    submission_date, art_unit, title, rejection_types, document_id and
    text_preview, plus metadata.facets.

Inputs: sort, limit, query, offset, +8 more.

odp_search_petition_decisionsA
Read-onlyIdempotent

Search USPTO decisions on patent petitions.

USE THIS TOOL WHEN: You need petition decisions on reviving abandoned
applications, reinstating patents after a missed maintenance fee,
delayed priority claims, petitions to make special, or supervisory
review of an examiner, or want to see how the Office of Petitions has
ruled on an argument (search its text with `query`). metadata.facets
gives outcome, deciding-office and petition-type counts for the whole
match set, so grant rates take one call.

Coverage: 1.1M decisions, 1991 on. The text is OCR and can be noisy
("EENITED STATES"), so prefer single terms or proximity
(ocrSearchText:"unintentional delay"~3) to long exact phrases. Typed
filters are AND-ed; pass a Lucene string in `query` for OR.

Args:
    query: Lucene query; bare words search everything, or name a field
           such as ocrSearchText:"unintentional delay"
    app_num: Application number without slashes
    patent_number: Patent number
    petition_type: Numeric petition type code (e.g. "533", reinstate
           patent for delayed maintenance fee) or words from its
           description (e.g. "revive")
    outcome: GRANTED, GRANTED-IN-PART, DENIED or DISMISSED
    deciding_office: e.g. "Office of Petitions", "Technology Center",
           "International Division"
    technology_center: e.g. "2600"
    date_from: Earliest decision date, YYYY-MM-DD
    date_to: Latest decision date, YYYY-MM-DD
    final_only: Only decisions marked final agency action (in the data
           so far, exactly the DENIED decisions)
    record_id: petitionDecisionRecordIdentifier from an earlier result
    include_full_text: Add each decision's full OCR text as full_text
           (about 1.5-3k characters each, prefixed by the record's
           metadata). Off by default.
    sort: "newest" (default) or "oldest" by decision date
    offset: Starting position (default: 0)
    limit: Max results (default: 25, at most 100)

Returns:
    Decisions with record_id, app_num, patent_number, dates, petition
    type, outcome, deciding office, final_decision, text (an excerpt,
    with query matches marked «like this») and documents (pass a
    documentIdentifier and app_num to odp_download_document with
    format="text" for the decision letter), plus metadata.facets.

Inputs: sort, limit, query, offset, +11 more.

ppubs_download_patent_pdfA
Read-onlyIdempotent

Download a patent as PDF (base64 encoded).

USE THIS TOOL WHEN: You need the official PDF document of a patent.
Note: Claude Desktop may not fully support PDF display.

Args:
    patent_number: Patent number ("7123456", "US 10,000,000 B2",
           "D845123" and "RE49123" all work).

Returns:
    Dictionary with base64-encoded PDF data.

Inputs: patent_number (required).

ppubs_get_citing_patentsA
Read-onlyIdempotent

Find later granted patents that cite a patent (forward citations).

USE THIS TOOL WHEN: You want to know who built on a patent, gauge its
influence, or find later art in the same space. This is the working
replacement for the decommissioned Enriched Citation API. For the
references a patent itself cites (backward citations), read its front
page instead: ppubs_get_patent_by_number(number, sections=["biblio"])
returns them in usRefGroup, foreignRefGroup and otherRefPub.

Searches the references-cited field (.urpn.) of granted patents.
Published applications do not index that field, so citing
applications that have not yet issued are not included. Verified live
2026-09-26.

Args:
    patent_number: The cited patent ("7123456", "US 10,000,000 B2",
           "D845123" and "RE49123" all work)
    offset: Starting position for pagination (default: 0)
    limit: Maximum results to return (default: 20, max: 500)
    sort: Sort order (default: "date_publ desc", newest citing patent first)

Returns:
    Normalized search response; `total` is the forward-citation count
    and each result is a citing patent with GUID, title, dates,
    inventors and classification.

Inputs: patent_number (required), sort, limit, offset.

ppubs_get_full_documentA
Read-onlyIdempotent

Get complete patent document by GUID from PPUBS.

USE THIS TOOL WHEN: You have a document GUID from search results
and need the patent text. A whole document runs 20-40k tokens, most
of it the description — ask for `sections` when you need less.

Args:
    guid: Document GUID (e.g., "US-9876543-B2")
    source_type: Document type - "USPAT" for patents, "US-PGPUB" for applications
    sections: Which parts to return; omit for everything. Any of
           "biblio" (front-page data: parties, dates, classification,
           references cited), "abstract", "claims", "description".
           ["biblio", "claims"] answers most questions in ~5k tokens.

Returns:
    Document with the requested sections. Empty fields and search
    highlight fields are dropped.

Inputs: guid (required), source_type (required), sections.

ppubs_get_patent_by_numberA
Read-onlyIdempotent

Get a granted patent's full text by patent number.

USE THIS TOOL WHEN: You know the patent number and need the patent
text. A whole document runs 20-40k tokens, most of it the
description — ask for `sections` when you need less.

Args:
    patent_number: Patent number. Separators, a leading "US" and a
           kind code are ignored, and design/reissue/plant prefixes
           are kept: "7123456", "US 10,000,000 B2", "D845123",
           "RE49123" all work.
    sections: Which parts to return; omit for everything. Any of
           "biblio" (front-page data: parties, dates, classification,
           references cited), "abstract", "claims", "description".
           ["biblio", "claims"] answers most questions in ~5k tokens.

Returns:
    Patent document with the requested sections. Empty fields and
    search highlight fields are dropped.

Inputs: patent_number (required), sections.

ppubs_search_applicationsA
Read-onlyIdempotent

Search published US patent applications in Patent Public Search.

USE THIS TOOL WHEN: You need to search pre-grant published applications
(applications publish 18 months after filing, before grant).

Args:
    query: Search query using USPTO BRS syntax (same as
           ppubs_search_patents). Multi-word terms are AND-ed —
           quote phrases that must appear together (e.g.
           '"machine learning"'). Field qualifiers are dotted
           suffixes (.ti., .ab., .in., .as., .cpc.) — the legacy
           slash-prefix forms (TTL/, IN/) no longer work.
    offset: Starting position for pagination (default: 0)
    limit: Maximum results to return (default: 20, max: 500). Results
           over the token budget are cut to 20 anyway, so raise this
           only when paging with `offset`.
    sort: Sort order (default: "date_publ desc")

Returns:
    Normalized response with application results.

Inputs: query (required), sort, limit, offset.

ppubs_search_patentsA
Read-onlyIdempotent

Search granted US patents in Patent Public Search (ppubs.uspto.gov).

USE THIS TOOL WHEN: You need full-text search of US patents with daily
updates, or need access to the most recent patent filings.

Args:
    query: Search query using USPTO BRS syntax. Multi-word terms are
           AND-ed across all fields by default — quote phrases that
           must appear together. Examples:
           - '"machine learning"' - exact phrase, all fields
           - machine learning - both terms anywhere (AND)
           - '"neural network".ti.' - title contains phrase
           - smith.in. AND IBM.as. - inventor Smith, assignee IBM
           - G06N3/08.cpc. - CPC classification
           Field qualifiers are dotted suffixes (.ti., .ab., .in.,
           .as., .cpc., .pn.) — the legacy slash-prefix forms
           (TTL/, IN/, AN/, CPC/) no longer work: they silently
           return 0 results, and TTL/"phrase" returns a server 500.
           Default `sort="date_publ desc"` means broad queries return
           the latest grants first — narrow with field qualifiers
           to get relevant matches.
    offset: Starting position for pagination (default: 0)
    limit: Maximum results to return (default: 20, max: 500). Results
           over the token budget are cut to 20 anyway, so raise this
           only when paging with `offset`.
    sort: Sort order (default: "date_publ desc")

Returns:
    Normalized response with patent results including GUID, title,
    abstract, dates, inventors, and classification codes.

Inputs: query (required), sort, limit, offset.

ptab_get_appealC
Read-onlyIdempotent

Get details of a specific ex parte appeal decision. Live via USPTO ODP v3.0.

Args:
    appeal_number: Appeal number

Inputs: appeal_number (required).

ptab_get_decisionB
Read-onlyIdempotent

Get details of a specific PTAB decision. Live via USPTO ODP v3.0.

Args:
    decision_id: Decision identifier (trial number, e.g. IPR2022-00001)

Inputs: decision_id (required).

ptab_get_documentsB
Read-onlyIdempotent

Get documents filed in a PTAB proceeding. Live via USPTO ODP v3.0.

Args:
    proceeding_number: Proceeding number (e.g., "IPR2023-00001")
    document_type: Filter by type (petition, response, declaration, etc.)
    offset: Starting position (default: 0)
    limit: Max results (default: 25)

Inputs: proceeding_number (required), limit, offset, document_type.

ptab_get_proceedingA
Read-onlyIdempotent

Get details of a specific PTAB proceeding. Live via USPTO ODP v3.0.

Args:
    proceeding_number: Proceeding number (e.g., "IPR2023-00001")

Returns:
    Proceeding details including parties, patent, status, and dates.

Inputs: proceeding_number (required).

ptab_search_appealsA
Read-onlyIdempotent

Search ex parte appeal decisions. Live via USPTO ODP v3.0.

Args:
    query: Full-text search query
    application_number: Filter by application number
    patent_number: Filter by patent number
    decision_date_from: Date range start (YYYY-MM-DD)
    decision_date_to: Date range end (YYYY-MM-DD)
    offset: Starting position (default: 0)
    limit: Max results (default: 25)

Inputs: limit, query, offset, patent_number, +3 more.

ptab_search_decisionsB
Read-onlyIdempotent

Search PTAB trial decisions. Live via USPTO ODP v3.0.

Args:
    query: Full-text search in decision text
    decision_type: Type (institution, final, termination)
    proceeding_number: Filter by proceeding number
    patent_number: Filter by patent number
    decision_date_from: Date range start (YYYY-MM-DD)
    decision_date_to: Date range end (YYYY-MM-DD)
    offset: Starting position (default: 0)
    limit: Max results (default: 25)

Inputs: limit, query, offset, decision_type, +4 more.

ptab_search_proceedingsA
Read-onlyIdempotent

Search PTAB trial proceedings (IPR, PGR, CBM, derivation).

USE THIS TOOL WHEN: You need to find patent validity challenges at
the Patent Trial and Appeal Board. Live via USPTO ODP v3.0.

Trial types:
- IPR: Inter Partes Review (most common, based on patents/publications)
- PGR: Post-Grant Review (broader grounds, within 9 months of grant)
- CBM: Covered Business Method (for financial method patents, sunsetted)
- DER: Derivation proceedings

Args:
    query: Full-text search query
    trial_type: Type of trial (IPR, PGR, CBM, DER)
    patent_number: Patent number being challenged
    party_name: Petitioner or patent owner name
    filing_date_from: Filing date range start (YYYY-MM-DD)
    filing_date_to: Filing date range end (YYYY-MM-DD)
    status: Proceeding status (Pending, Instituted, Terminated, FWD Entered)
    offset: Starting position (default: 0)
    limit: Max results (default: 25)

Returns:
    Normalized response with matching proceedings.

Inputs: limit, query, offset, status, +5 more.

tm_get_trademarkA
Read-onlyIdempotent

Get a trademark's search-index record by serial number.

USE THIS TOOL WHEN: You have a serial number from tm_search_trademarks
results and want the full indexed record. For authoritative live status,
prefer tsdr_get_trademark_status.

Args:
    serial_number: 8-digit application serial number (e.g., "78787878")

Returns:
    Normalized response with the trademark record.

Inputs: serial_number (required).

tm_search_assignmentsA
Read-onlyIdempotent

Search recorded trademark assignment (ownership transfer) records.

USE THIS TOOL WHEN: You need to trace ownership history of a trademark,
find the current owner, or find marks transferred to/from a company.
Covers recorded assignments from 1955 to present, via the USPTO
Assignment Center public API (no API key required).

At least one filter is required; multiple filters combine (AND).

Args:
    serial_number: Trademark application serial number
    registration_number: Trademark registration number
    assignee_name: Assignee (new owner) name
    assignor_name: Assignor (previous owner) name
    reel_frame: Recordation reel/frame identifier (e.g., "9006/0093")
    offset: Starting position for pagination (default: 0)
    limit: Maximum results to return (default: 25)

Returns:
    Normalized response with assignment records (reel/frame, assignors,
    assignees, conveyance, and affected properties).

Inputs: limit, offset, reel_frame, assignee_name, +3 more.

tm_search_trademarksA
Read-onlyIdempotent

Search US federal trademark applications and registrations.

USE THIS TOOL WHEN: You need to find trademarks by mark text, owner,
goods/services description, or Nice/international class — e.g.
clearance/knockout searches for a proposed mark, or mapping a company's
trademark portfolio.

NOTE: Backed by the undocumented internal API behind tmsearch.uspto.gov
(the TESS replacement) — same risk profile as PPUBS; may break without
notice. For authoritative status of a specific mark, use
tsdr_get_trademark_status. Federal marks only (no common-law/state marks).

Args:
    query: Raw query string for advanced searches
    mark_text: Word mark text to search (e.g., "ACME")
    owner_name: Owner/applicant name to search
    goods_services: Goods/services description terms (e.g., "athletic
        footwear") — useful for clearance searches across wording
    registration_number: Exact registration number to look up
    international_class: Nice class number 1-45 (e.g., "9" for software;
        use get_trademark_class_info to look up classes)
    status_filter: "live" (active marks), "dead" (abandoned/cancelled/
        expired), or omit for both
    offset: Starting position for pagination (default: 0)
    limit: Maximum results to return (default: 25, max: 100)

Returns:
    Normalized response with matching trademark records.

Inputs: limit, query, offset, mark_text, +5 more.

tsdr_download_trademark_documentsA
Read-onlyIdempotent

Download the prosecution document bundle for a trademark as PDF (base64).

USE THIS TOOL WHEN: You need office actions, responses, specimens, or
other file-wrapper documents for a trademark application.

NOTE: TSDR limits PDF downloads to 4 requests per minute per API key,
and unfiltered full wrappers can exceed 10 MB (rejected with
RESPONSE_TOO_LARGE above 4 MB). Call tsdr_list_trademark_documents
first, then filter by document_type and/or date range.

Args:
    serial_number: 8-digit application serial number (e.g., "78787878")
    document_type: Optional document type filter (e.g., "OOA" for
        outgoing office actions, "SPE" for specimens)
    date_from: Optional start date filter (YYYY-MM-DD)
    date_to: Optional end date filter (YYYY-MM-DD)

Returns:
    Dictionary with base64-encoded PDF data.

Inputs: serial_number (required), date_to, date_from, document_type.

tsdr_get_trademark_imageA
Read-onlyIdempotent

Get the mark image (drawing) for a trademark as base64.

USE THIS TOOL WHEN: You need the visual representation of a design mark
or stylized word mark.

Args:
    serial_number: 8-digit application serial number (e.g., "78787878")

Returns:
    Dictionary with base64-encoded image data.

Inputs: serial_number (required).

tsdr_get_trademark_statusA
Read-onlyIdempotent

Get current status of a trademark application or registration from TSDR.

USE THIS TOOL WHEN: You have a trademark serial number or registration
number and need its authoritative live status, mark text, owner,
international classes, filing/registration dates, or prosecution stage.
TSDR is the official USPTO status source (requires API key).

Exactly one of serial_number or registration_number is required.

Args:
    serial_number: 8-digit application serial number (e.g., "78787878")
    registration_number: Registration number (e.g., "3500027")

Returns:
    Normalized response with the trademark status record.

Inputs: serial_number, registration_number.

tsdr_list_trademark_documentsA
Read-onlyIdempotent

List prosecution document metadata for a trademark (no downloads).

USE THIS TOOL WHEN: You want to see what file-wrapper documents exist
for a trademark application (office actions, responses, specimens,
registration certificates) before downloading anything. Unlike
tsdr_download_trademark_documents, this returns metadata only and is
NOT subject to the 4 req/min PDF rate limit. Use the DocumentTypeCode
values it returns (e.g. "OOA", "SPE") as the document_type filter when
downloading.

Args:
    serial_number: 8-digit application serial number (e.g., "78787878")

Returns:
    Document metadata records (type, description, dates).

Inputs: serial_number (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 42 tools

    Disambiguation4/5

    Descriptions do real work separating near-neighbors: ppubs_search_patents vs ppubs_search_applications vs odp_search_applications, and tm_get_trademark vs tsdr_get_trademark_status explicitly say which to prefer. A few pairs remain easy to confuse (odp_get_application vs odp_get_application_metadata, get_status_code vs get_trademark_status_code, odp_get_documents vs tsdr_list_trademark_documents), but they are scoped to different resources or domains.

    Naming Consistency4/5

    The dominant pattern is domain-prefix + verb_noun (odp_, ppubs_, ptab_, tsdr_, tm_) with consistent verbs (get_, search_, list_, download_). The deviation is a set of bare get_/check_ tools (get_cpc_info, get_status_code, get_office_action_citations, get_office_action_rejections, check_api_status) that break the prefix convention even though some of them clearly belong to the ODP family.

    Tool Count3/5

    42 tools is heavy and above the comfortable band, though the server genuinely spans five distinct USPTO data domains (ODP applications, PPUBS patents, PTAB, TSDR/trademarks, classification lookups). Most tools cover a distinct endpoint, but redundancy (two application-search tools, application vs application-metadata, tm_get_trademark vs tsdr_get_trademark_status) means not every tool clearly earns its slot.

    Completeness4/5

    Coverage is broad: search/get/download across patents, applications, office actions, petitions, PTAB trials/appeals, trademarks, assignments, CPC and status codes, plus dataset and API-status tools. Minor gaps remain — patent assignment lookup is only by application number, PTAB document bodies lack a direct download path, and maintenance-fee/expiration lifecycle data is only partially covered via PTA.

    Maintenance

    ActivityActive
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers