Prior-art exploration MCP server; finds related patents, never judges infringement
862
日本語版: README_ja.md
Patent Checker helps you explore published patents that may relate to your own software project, and to write down what you found as a dated, procedure-style report. It is meant to be run more than once on the same project — as an idea, during development, before a release, before each update: a later run searches only what is new, re-checks the patents you are monitoring, and tells you what changed since last time. It is built from two parts:
Patent Checker does not decide whether anything infringes a patent. Its reports contain observations, scope statements and open questions, never a verdict.
Status: stable release (v1.3).
Please read these before you install anything. The tool asks you to acknowledge them once, and records that you did.
There are two notices. The user notice (the three points above) is shown by the Skill to whoever runs an exploration, and by the installer up front; your agreement is recorded locally and checked before every run. The operator notice is for whoever starts the server: it covers data-source terms, credentials, and what the server stores, and the server refuses to start until it has been acknowledged.
your agent ──(Skill: judgment)──► patent-checker MCP server ──► EPO OPS
│ │ deterministic fetch, Google Patents
│ reads your code, writes │ normalization, cache
▼ the report ▼
.patent-checker/reports/… shared document cache
The server only ever receives public patent data: search expressions, publication numbers, family identifiers, dates, and status snapshots it returned earlier. Your source code, your project description and the ledger never leave your machine: the analysis happens inside your agent.
The server listens on HTTP, and every MCP client must present a bearer token on every request: a secret string that only your server and your own agents know. It is what stops any other program on the machine, or on the network if you ever expose the port, from using your server and your EPO OPS quota. There is no account or sign-up behind it; you make the token yourself, once, and give the same value to the server and to the installer.
Generate one (any 32 random bytes will do):
python3 -c "import secrets; print(secrets.token_urlsafe(32))" # macOS, Linux
python -c "import secrets; print(secrets.token_urlsafe(32))" # Windows
Where it goes:
secrets/server_token.txt next to
compose.yaml..env as PATENT_CHECKER_SERVER_TOKEN=… (or a
file named by PATENT_CHECKER_SERVER_TOKEN_FILE).patent-checker install asks for it (or reads it from
--token-file), and writes it into each agent's MCP configuration.Without a token the HTTP server does not start. The one exception is
patent-checker serve --transport stdio, which has no token because the
agent starts the server as a child process running with your own
permissions; that is a special case for a single local client, not the
default. Treat the token like a password: keep the files that hold it
private, and rotate it by writing a new value and re-running
patent-checker install.
If you leave the OPS credentials unset (empty secrets/ops_key.txt and
ops_secret.txt, or no PATENT_CHECKER_OPS_KEY in .env), the server
starts in degraded mode and says so at start-up and in server_status.
Degraded mode is meant for a first look. For a real exploration, get an OPS account and restart the server with the credentials in place.
Both routes need the operator notice acknowledged and a bearer token.
mkdir patent-checker-server && cd patent-checker-server
curl -fsSLO https://raw.githubusercontent.com/xhighhongo41/patent-checker/main/compose.yaml
mkdir secrets
# 1. EPO OPS credentials (or leave both files empty for degraded mode)
printf '%s' 'YOUR_OPS_CONSUMER_KEY' > secrets/ops_key.txt
printf '%s' 'YOUR_OPS_CONSUMER_SECRET' > secrets/ops_secret.txt
# 2. The bearer token (see above)
python3 -c "import secrets; print(secrets.token_urlsafe(32))" > secrets/server_token.txt
chmod 600 secrets/*.txt
# 3. Read the operator notice (add --lang ja for Japanese), then acknowledge it
docker compose run --rm patent-checker serve --show-operator-notice
echo 'PATENT_CHECKER_OPERATOR_CONSENT=1.0' >> .env
# 4. Start
docker compose up -d
curl -fsS http://127.0.0.1:8642/health
On Windows, create the three files with PowerShell instead of printf
(Set-Content writes a byte-order mark that would become part of the
token, so use .NET directly):
New-Item -ItemType Directory -Force secrets | Out-Null
New-Item -ItemType File -Force secrets\ops_key.txt, secrets\ops_secret.txt | Out-Null # empty: degraded mode
$token = python -c "import secrets; print(secrets.token_urlsafe(32))"
[IO.File]::WriteAllText("$PWD\secrets\server_token.txt", $token)
The image is published as ghcr.io/xhighhongo41/patent-checker and
docker.io/xhighhongo41/patent-checker with tags X.Y.Z, X.Y and
latest. The container binds 0.0.0.0 internally, but Compose publishes
the port on your machine's loopback only (127.0.0.1:8642). The Host
headers the server accepts are the loopback names localhost, 127.0.0.1
and ::1, which its HTTP layer always allows, plus any name you add with
PATENT_CHECKER_SERVER_ALLOWED_HOSTS — nothing else.
Fetched documents, search results and the request log live in the named
volume patent-checker-data. The container runs as an unprivileged user
on a read-only filesystem with all Linux capabilities dropped; if your
Docker engine rejects one of those settings, the four lines under
# Hardening in compose.yaml can be removed without changing what the
server does.
The secret files are read once at start; empty OPS files mean "not
configured" (degraded mode). If you run Docker Engine on Linux under an
account that is not UID 1000, see the note on file ownership in
secrets/README.md.
To share one server between several machines (a tailnet, a VPN, a LAN), see docs/deploy-lan.md: it covers Tailscale Serve, a TLS-terminating proxy in front of the same container, and plain HTTP on a private network, and what each leaves to you.
uv tool install patent-checker
mkdir patent-checker-server && cd patent-checker-server
curl -fsSLO https://raw.githubusercontent.com/xhighhongo41/patent-checker/main/.env.example
cp .env.example .env
Then edit .env:
PATENT_CHECKER_OPS_KEY and
PATENT_CHECKER_OPS_SECRET (leave them empty for degraded mode).PATENT_CHECKER_SERVER_TOKEN.patent-checker serve --show-operator-notice
(add --lang ja for Japanese) and set
PATENT_CHECKER_OPERATOR_CONSENT=1.0.A minimal .env looks like this:
PATENT_CHECKER_OPS_KEY=YOUR_OPS_CONSUMER_KEY
PATENT_CHECKER_OPS_SECRET=YOUR_OPS_CONSUMER_SECRET
PATENT_CHECKER_SERVER_TOKEN=the-token-you-generated
PATENT_CHECKER_OPERATOR_CONSENT=1.0
Start the server with patent-checker serve. It speaks Streamable HTTP on
http://127.0.0.1:8642/mcp. The .env file is looked up in the directory
you start from and its parents, stopping short of your home directory and
the filesystem root; variables already in the environment win. Data goes
to the per-user data directory (~/.local/share/patent-checker on Linux
and macOS, %LOCALAPPDATA%\patent-checker on Windows). If the port is
already taken, the server stops with a message; pick another with
--port and register that URL with your agents.
--transport stdio runs the server without a network port and without
a token, for a single local client only; it then runs with your user's
permissions, which is why HTTP is the default. How to register it with an
agent is in docs/mcp-clients.md.
The bootstrap script installs the command-line tool; patent-checker install does the rest — it shows the user notice, copies the Skill into
the places your agents read, and registers the MCP server with them:
curl -LsSf https://raw.githubusercontent.com/xhighhongo41/patent-checker/main/install.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/xhighhongo41/patent-checker/main/install.ps1 | iex"
Both scripts install uv and the tool and then continue into
patent-checker install. Piped into sh as above, the shell script's
standard input is the pipe, so it asks its questions on your terminal
instead; only when there is no terminal at all (a CI job, say) does it
stop and print the patent-checker install command for you to run next.
Prefer to read the script first? Fetch it with | more instead of | sh,
or skip it entirely — the two steps it takes are:
uv tool install patent-checker
patent-checker install
patent-checker install:
~/.config/patent-checker/consent.json with the date and notice
version; you are asked again only when the notice changes);--token-file);~/.agents/skills/patent-checker/ (read by Codex
CLI, OpenCode, Cursor, Gemini CLI and Copilot CLI) and into the private
directories of the agents that need one (~/.claude/skills/,
~/.openhands/skills/, ~/.hermes/skills/);http://127.0.0.1:8642/mcp unless you pass
--url) with each detected agent, using the agent's own mcp add
command where one exists (Claude Code, Gemini CLI, Copilot CLI, Codex
CLI with --token-env), editing the agent's JSON or TOML configuration
otherwise (Cursor, OpenCode, Codex CLI), and printing a snippet to paste
for the agents whose configuration it will not touch (Hermes Agent, and
OpenHands when its CLI is not installed);| Agent | Registered by | Configuration file |
|---|---|---|
| Claude Code | claude mcp add | user settings (.mcp.json with --scope project) |
| Gemini CLI | gemini mcp add | ~/.gemini/settings.json |
| GitHub Copilot CLI | copilot mcp add | ~/.copilot/mcp-config.json |
| Cursor | edited in place | ~/.cursor/mcp.json |
| OpenCode | edited in place | ~/.config/opencode/opencode.json |
| Codex CLI | codex mcp add / appended | ~/.codex/config.toml |
| OpenHands | openhands mcp add (snippet to paste without the CLI) | managed by the OpenHands CLI |
| Hermes Agent | snippet to paste | ~/.hermes/config.yaml |
OpenCode's file follows XDG_CONFIG_HOME when it is set. The Gemini CLI,
Copilot CLI and OpenHands commands are used as their documentation
describes but have not been tried against the real tools; when one fails,
the installer falls back to editing the file or to a snippet, and says so.
Useful options: --list-agents (what would be installed where),
--dry-run (do everything except write), --agent claude-code --agent cursor
(instead of auto-detection; --agent all for every supported agent),
--scope project (install into the current project instead of your home
directory), --lang ja (Japanese notice), --agree (agree to the notice
without being asked — required when there is no terminal to ask at),
--no-skill / --no-mcp, --json (print the report as one JSON document,
for scripts; the notice and questions then go to standard error).
Re-running the installer is safe: it refreshes the Skill copies and updates
the server entry in place, and it never overwrites the backup (.bak) it
made of your original configuration file on the first run. The one
exception is Codex CLI, whose existing entry is left alone; edit
~/.codex/config.toml to change it.
The installer never takes the token as a command-line argument, so it does not land in your shell history. Give it one of:
patent-checker install --token-file /path/to/secrets/server_token.txt
# or
export PATENT_CHECKER_SERVER_TOKEN="$(cat /path/to/secrets/server_token.txt)"
patent-checker install
# or just run it: the installer prompts for the token without echoing it
By default the token value is written into each agent's own configuration
file, which is then made readable by you alone (on Windows the file keeps
its usual permissions). With --token-env the installer does not need the
value at all: it writes a reference to the PATENT_CHECKER_SERVER_TOKEN
environment variable, in the notation each agent expands, and you export
that variable before starting the agent. Copilot CLI and OpenHands do not
document such references, so --token-env prints a snippet for them
instead. When an agent's own CLI is used for registration, the token
appears in that process's arguments for the duration of the call.
With --scope project, the configuration file that holds the token is
written inside your project directory. The installer reminds you: do not
commit it.
Registration commands and snippets that the installer prints never contain
the token; they use ${PATENT_CHECKER_SERVER_TOKEN} or a placeholder.
A 401 means the token the agent sends is not the one the server was
started with. Compare the two: the server's is in secrets/server_token.txt
or .env; the agent's is in the configuration file from the table above
(Claude Code shows it with claude mcp get patent-checker). Make sure a
placeholder such as <token> did not get registered verbatim. A server
that is not running produces a connection refused error, not a 401, so
the two are easy to tell apart.
The exact command or file for each agent, the GitHub Copilot coding agent, and the stdio form are in docs/mcp-clients.md.
Commit the Skill into your repository as .agents/skills/patent-checker/
(patent-checker install --scope project --no-mcp, then add the directory
to git), and run the server somewhere the cloud agent can reach over HTTPS
(docs/deploy-lan.md). The consent record is per
user; a cloud agent whose home directory is reset records it again on the
next run, or use patent-checker consent record --project to keep it with
the project.
Ask your agent for a prior-art exploration of the project it is working in:
Use the patent-checker skill to explore prior patents related to this project.
The Skill first checks the consent record, asks (once per project) whether
.patent-checker/ should be added to .gitignore, then works through the
steps above and writes the report to
.patent-checker/reports/report-<target>-<YYYYMMDD-HHMM>.md. Reports are
never overwritten; a later run of the same project produces a new, dated
file. <target> is the name of what is being checked — your repository's
name unless you and your agent agree on another one — and each target keeps
its own ledger under .patent-checker/ledger/<target>/. Keep the server
running for the whole session.
Scale and cost. One exploration of a medium-sized project involves reading your code, one or more search rounds, and a staged screening of a few dozen candidate documents. Expect it to consume on the order of a million tokens of agent traffic (measured with Claude Code on a medium-sized project during development), most of it in screening; the Skill hands the first screening stage to smaller models where your agent supports delegation. One run is not exhaustive: repeated runs, different query vocabularies and a professional search will each find things a single run does not.
Ask again whenever the project has moved on, or when the date of the next check in the report has come:
Use the patent-checker skill to follow up on the earlier exploration of this project.
The Skill finds the ledger under .patent-checker/ledger/<target>/ and
proposes one of two kinds of run:
update-<target>-<YYYYMMDD-HHMM>.md. It costs a small fraction of
an exploration, and says plainly that nothing was searched.Nothing is downloaded twice: claims stay in the cache for good, legal status is refreshed after a week and families after a month, and every result says when it was fetched, so a report can state what its facts are "as of". Measured during development, three weeks after the first exploration of a medium-sized project: the 17 stored queries returned 11 hits for the new publication window instead of 712 for all time, 8 of them in families that had been screened already, and all 25 monitored patents were re-checked with about fifty upstream requests; a monitoring run made the same day needed none. If you explored a project with an earlier version, the Skill offers to import the latest report into a ledger first.
If the server cannot be reached, the Skill carries on with the
patent-checker command-line tool on your machine, which offers the same
operations (see the command reference below). It asks before anything is
installed. To prepare a machine for that, or to run the commands yourself:
uv tool install patent-checker
patent-checker credentials set # asks for the EPO OPS key and secret without echoing them
patent-checker status # what is configured, and where from; no network
credentials set stores the key and secret for your user in
~/.config/patent-checker/credentials.env (readable by you only), so the
tool finds them from any project. Values in the environment or in a
project's .env take precedence over that file; patent-checker credentials status tells which one is used, and credentials clear deletes the file.
Without OPS credentials the Skill offers the degraded mode. Update and
remove the tool with uv tool upgrade patent-checker and uv tool uninstall patent-checker.
Environment variables read by the server (patent-checker serve) and,
where noted, by the CLI. See .env.example for the same list with
comments. The CLI's --host and --port options override
PATENT_CHECKER_SERVER_HOST and PATENT_CHECKER_SERVER_PORT.
| Variable | Default | Meaning |
|---|---|---|
PATENT_CHECKER_OPS_KEY, PATENT_CHECKER_OPS_SECRET | unset | EPO OPS consumer key and secret. Either the value, or the path to a file holding it via the _FILE variants (PATENT_CHECKER_OPS_KEY_FILE, …); never both. Empty files mean "not configured" (degraded mode). When none of the four is set, the per-user credentials file is read. |
Content type
Image
Digest
sha256:915d1b0eb…
Size
73.9 MB
Last updated
2 days ago
docker pull xhighhongo41/patent-checker