loading…
Search for a command to run...
loading…
Enables natural language access to Japanese patent information through the JPO API, allowing users to query patent data directly from Claude Desktop or Claude C
Enables natural language access to Japanese patent information through the JPO API, allowing users to query patent data directly from Claude Desktop or Claude Code.
License: MIT Python 3.12+ MCP CI GitHub release
English · 日本語
Query Japanese patents in natural language from Claude. IP-MCP wraps the Japan Patent Office's official "Patent Information Retrieval API" as an MCP server, so Claude Desktop, Claude Code, and iPhone Claude can resolve patent numbers, check registration status, pull citations, and walk five-office families — 12 official-API tools plus 1 deliberately isolated keyword-search tool.
You: "Tell me the registration status and prior art of JP-2010-228687."
Claude (under the hood):
jpo_convert_patent_number→ application number2009080841jpo_get_patent_registration→ registration 5094774, Hitachi Ltd., expires 2029-03-30, alivejpo_get_patent_citations→ 20 prior-art referencesReply: "Train Control Ground Equipment and System" (Hitachi Ltd.) was registered as JP5094774 on 2012-09-28, currently in force, due 2029-03-30. 20 prior-art citations from search report and rejection grounds, all patent literature (no NPL)…
Keyword search is split into a separate tool (external_search_patents_by_keyword, Google Patents XHR). The LLM can never accidentally fall back from the official API to the unofficial source — every response carries an explicit source field.
| J-PlatPat (manual web UI) | Hand-rolled Flask wrapper | IP-MCP | Hitting Google Patents directly | |
|---|---|---|---|---|
| Data source | Official (JPO) | Official (JPO) | Official (JPO) + external (optional) | Unofficial |
| Number convert / progress / registration / citations | ✓ (by hand) | ✓ | ✓ | ❌ |
| Keyword search | ✓ | ✓ | △ (isolated external tool) | ✓ |
| Callable directly from an LLM | ❌ | ❌ (REST + parsing needed) | ✅ native MCP | △ (HTML/JSON parsing needed) |
| Official vs. unofficial distinction | — | single source | ✅ mandatory source field |
— |
| Automatic fallback | — | — | ❌ forbidden (the LLM decides) | — |
| Auth | session | env | env or OAuth 2.1 (DCR + PKCE) | none |
| Deploy | — | DIY | Docker Compose | — |
The official JPO API is number-lookup only — every endpoint takes an application / publication / registration number, an applicant code, or an exact-match applicant name. Keyword / IPC / F-term / date-range / partial-name search does not exist in the spec. So:
tools_official/ — names start with jpo_*, response is {"source": "jpo_official", …}tools_external/ — names start with external_*, response is {"source": "google_patents_unofficial", …}import from tools_external/ into tools_official/. No silent fallback — the LLM decides whether to consult the unofficial source.flowchart LR
User["Claude Desktop /<br/>Claude Code /<br/>iPhone Claude"]
CF["Cloudflare<br/>(Edge TLS + Tunnel)"]
Caddy["Caddy<br/>(CF Origin Cert)"]
User -->|"HTTPS + OAuth"| CF
CF -->|"outbound from home<br/>via cloudflared"| Caddy
Caddy -->|"http+SSE"| MCP
subgraph Docker["Docker container (Python 3.12 + FastMCP)"]
MCP["MCP server<br/>:8765"]
Official["tools_official/<br/>(jpo_* 12 tools)"]
External["tools_external/<br/>(external_* 1 tool)"]
OAuth["OAuth 2.1<br/>SQLite-backed"]
MCP --> Official
MCP --> External
MCP -.->|"persisted"| OAuth
end
Official -->|"OAuth2 password grant"| JPO[("JPO Patent API")]
External -->|"3s spacing + 503 backoff"| GP[("Google Patents XHR")]
classDef boundary stroke-dasharray: 5 5
class External,GP boundary
Core design rules:
tools_official/ (official JPO) and tools_external/ (unofficial Google Patents) are fully separated at the code-hierarchy, call-site, and logger level. A boundary test blocks any import from tools_external/ into tools_official/.{"source": "jpo_official"} or {"source": "google_patents_unofficial"}.cp .env.example .env # Fill in JPO_USERNAME / JPO_PASSWORD
chmod 600 .env
docker compose up -d --build
Create docker-compose.override.yml to bind to your LAN interface (the repo ships a docker-compose.override.yml.example):
services:
ip-mcp:
ports:
- "YOUR_SERVER_IP:8765:8765" # your LAN IP
Claude Desktop / Code config:
{
"mcpServers": {
"ip-mcp": {
"transport": { "type": "sse", "url": "http://YOUR_SERVER_IP:8765/sse" }
}
}
}
Codex CLI's direct HTTP MCP (codex mcp add --url) expects Streamable HTTP, so register the /mcp path when using it directly from Codex:
CODEX_HOME=/path/to/codex-home codex mcp add ip-mcp --url https://your-host.example.com/mcp
CODEX_HOME=/path/to/codex-home codex mcp login ip-mcp
SSE clients register /sse. To serve Codex direct HTTP and SSE clients from the same public server, start with MCP_TRANSPORT=both to expose both /mcp and /sse under the same OAuth config. For a single client, MCP_TRANSPORT=sse (default) or MCP_TRANSPORT=streamable-http also works.
For public exposure the recommended setup is Cloudflare Tunnel + Caddy (CF Origin Cert) — cloudflared dials out from your home network to the CF edge, so no router port forwarding is needed and hairpin NAT is a non-issue. A traditional reverse proxy with Let's Encrypt + direct 443 also works. Either way, set MCP_OAUTH_MASTER_PASSWORD + MCP_OAUTH_ISSUER_URL to enable OAuth 2.1 (DCR + PKCE + master-password consent). Issued client tokens persist to SQLite and survive container restarts.
MCP_OAUTH_MASTER_PASSWORD=<24+ chars random>
MCP_OAUTH_ISSUER_URL=https://your-host.example.com
# optional: MCP_OAUTH_DB_PATH=/app/data/oauth.db
See PLAN.md §9-§10 and OPERATIONS.md for full deployment + operations details (Japanese for now).
| Name | Purpose |
|---|---|
jpo_convert_patent_number |
Convert between application / publication / registration numbers |
jpo_get_patent_progress |
Examination progress (full / simple toggle) |
jpo_get_patent_registration |
Registration info & right status |
jpo_get_patent_citations |
Cited prior-art documents |
jpo_get_divisional_apps |
Divisional applications |
jpo_get_priority_apps |
Priority-basis applications |
jpo_lookup_applicant |
Applicant code ⇄ name (exact match only) |
jpo_get_patent_documents |
Office actions / refusal reasons / amendments (handles inline ZIP + signed URL) |
jpo_get_jpp_url |
J-PlatPat canonical URL |
jpo_get_opd_family |
Five-office patent family (JPO / USPTO / EPO / CNIPA / KIPO) |
jpo_get_opd_doc_list |
OPD document list |
jpo_fetch_full_record |
High-level composite fanning out to multiple official endpoints (stays entirely within the official API) |
Response: {"ok": true, "source": "jpo_official", "data": {…}, "remaining_today": "…"}
| Name | Purpose |
|---|---|
external_search_patents_by_keyword |
Free-text / assignee / IPC / date-range search of Japanese patents (Google Patents XHR, reference use) |
Response: {"ok": true, "source": "google_patents_unofficial", "data": {…}}
Isolated because the official API offers no keyword search (number-lookup only). On failure it returns {"ok": false, "kind": "search_unavailable"} and never falls back to an official tool.
The official JPO API delegates self-throttling responsibility to the operator:
/api/patent/* is 10 req/min, /opdapi/* is 5 req/min (OPD is counted separately on its own bucket).result.remainAccessCount, returned on every response.jpo_fetch_full_record fans out to 4 official endpoints in parallel, so one call consumes 1 unit from each of 4 separate daily quotas (not 4 from the same quota). The bottleneck is whichever quota is lowest.For the tool-to-endpoint mapping and operational thresholds, see OPERATIONS.md §JPO API レート制約とクォータ (Japanese).
| Placeholder | Example | How to set |
|---|---|---|
YOUR_SERVER_IP |
192.0.2.10 |
LAN IP of your deployment host |
<SSH_USER> |
youruser |
SSH username on the host |
your-host.example.com |
your own domain | public hostname behind Cloudflare / your reverse proxy |
The port binding in docker-compose.yml defaults to 127.0.0.1:8765 (same-machine only). To expose on the LAN, create a separate docker-compose.override.yml (already gitignored) to override it.
MIT — see LICENSE.
Выполни в терминале:
claude mcp add ip-mcp -- npx Да, IP MCP бесплатный — установка в один клик через Unyly без оплаты.
Нет, IP работает без API-ключей и переменных окружения.
Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.
Открой IP на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
CSA PROJECT - FZCO © 2026 IFZA Business Park, DDP, Premises Number 31174 - 001
Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.