
Korean Patent Search
Search Korean KIPRIS patent bibliographies and abstracts before committing to a product or feature direction.
Overview
Korean Patent Search is an agent skill for the Idea phase that queries the KIPRIS Plus API for Korean patent search hits and bibliography details.
Install
npx skills add https://github.com/nomadamas/k-skill --skill korean-patent-searchWhat is this skill?
- Calls KIPRIS Plus patent utility search and bibliography detail operations over HTTPS
- Parses XML responses into structured fields (application number, title, status, IPC, abstract, applicants, drawings)
- Configurable query, page size, and page number for paginated word search
- Requires KIPRIS_PLUS_API_KEY environment variable for authenticated API access
- CLI-oriented Python module with dataclass result types for agent or script invocation
- Two KIPRIS operations: getWordSearch and getBibliographyDetailInfoSearch
- Default request timeout of 30 seconds
Adoption & trust: 2.3k installs on skills.sh; 5.4k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are exploring a product idea but have no fast, structured way to search Korean patents and pull key bibliographic fields into your agent workflow.
Who is it for?
Solo builders doing Korean-market or Korea-registered IP research with a KIPRIS Plus API key who want scripted search from Claude Code, Cursor, or Codex.
Skip if: Teams needing certified legal FTO analysis, non-Korean patent databases only, or workflows without network access and an approved KIPRIS API key.
When should I use this skill?
User needs Korean patent word search or detailed bibliography fields from KIPRIS Plus during research.
What do I get? / Deliverables
You get paginated, parsed patent records (titles, status, dates, IPC, abstracts, applicants) ready to compare against your concept before you scope a build.
- Structured patent search result list for a query and page
- Bibliography detail fields for a chosen application number
Recommended Skills
Journey fit
Patent and prior-art checks belong at the earliest research step when you are still deciding what to build. Competitive and IP discovery sits in idea-phase research alongside market and technical scouting.
How it compares
Use this skill package for KIPRIS Plus API search—not a generic web scrape or a USPTO/EPO integration.
Common Questions / FAQ
Who is korean-patent-search for?
Indie and solo builders researching Korean patents and prior art during idea validation, especially when agents need structured API results instead of manual portal clicks.
When should I use korean-patent-search?
Use it in the Idea research phase when you need word search or bibliography details from KIPRIS before committing to scope, and when comparing competitor filings in Korea.
Is korean-patent-search safe to install?
Review the Security Audits panel on this Prism page before installing; the skill needs network access and a secrets-backed API key, so treat the key like production credentials.
SKILL.md
READMESKILL.md - Korean Patent Search
from __future__ import annotations import argparse import json import os import sys import urllib.error import urllib.parse import urllib.request import xml.etree.ElementTree as ET from dataclasses import asdict, dataclass from html.parser import HTMLParser from typing import Callable SERVICE_KEY_ENV_VAR = "KIPRIS_PLUS_API_KEY" DEFAULT_TIMEOUT = 30 DEFAULT_NUM_ROWS = 10 DEFAULT_PAGE_NO = 1 BASE_API_URL = "https://plus.kipris.or.kr/kipo-api/kipi/patUtiModInfoSearchSevice" SEARCH_OPERATION = "getWordSearch" DETAIL_OPERATION = "getBibliographyDetailInfoSearch" DEFAULT_HEADERS = { "Accept": "application/xml,text/xml;q=0.9,*/*;q=0.8", "User-Agent": ( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36" ), } @dataclass(frozen=True) class PatentSearchResult: index_no: int | None application_number: str invention_title: str | None register_status: str | None application_date: str | None open_number: str | None open_date: str | None publication_number: str | None publication_date: str | None register_number: str | None register_date: str | None ipc_number: str | None abstract_text: str | None applicant_name: str | None drawing: str | None big_drawing: str | None @dataclass(frozen=True) class PatentSearchResponse: query: str page_no: int num_of_rows: int total_count: int items: list[PatentSearchResult] @dataclass(frozen=True) class PatentDetail: application_number: str invention_title: str | None register_status: str | None application_date: str | None open_number: str | None open_date: str | None publication_number: str | None publication_date: str | None register_number: str | None register_date: str | None ipc_number: str | None abstract_text: str | None applicant_name: str | None drawing: str | None big_drawing: str | None @dataclass class XmlNode: tag: str children: list["XmlNode"] text_chunks: list[str] @property def text(self) -> str: return "".join(self.text_chunks) class XmlNodeBuilder(HTMLParser): def __init__(self) -> None: super().__init__(convert_charrefs=True) self.root: XmlNode | None = None self.stack: list[XmlNode] = [] def handle_starttag(self, tag: str, attrs) -> None: # type: ignore[override] node = XmlNode(tag=tag, children=[], text_chunks=[]) if self.stack: self.stack[-1].children.append(node) else: self.root = node self.stack.append(node) def handle_endtag(self, tag: str) -> None: # type: ignore[override] if self.stack: self.stack.pop() def handle_data(self, data: str) -> None: # type: ignore[override] if self.stack: self.stack[-1].text_chunks.append(data) def clean_text(value: str | None) -> str | None: if value is None: return None cleaned = " ".join(value.split()).strip() return cleaned or None def parse_positive_int(raw_value: str) -> int: value = int(raw_value) if value <= 0: raise argparse.ArgumentTypeError("must be a positive integer") return value def resolve_service_key(explicit_key: str | None = None) -> str: candidate = clean_text(explicit_key) or clean_text(os.getenv(SERVICE_KEY_ENV_VAR)) if candidate: return urllib.parse.unquote(candidate) raise ValueError( f"missing {SERVICE_KEY_ENV_VAR}. Export {SERVICE_KEY_ENV_VAR} or pass --service-key " "(mapped to the KIPRIS Plus ServiceKey query parameter)." ) def build_operation_url(operation: str) -> str: return f"{BASE_API_URL}/{operation}" def build_search_params( *, query: str, year: int | None = None, page_no: int = DEFAULT_PAGE_NO, num_of_rows: int = DEFAULT_NUM_ROWS, patent: bool = True, utility: bool = True, ser