nl-openapi-mcp
๐ ์ฌ์ฉ๋ โ ์ต๊ทผ 14์ผ ์กฐํ 7ํ(๊ณ ์ 4) ยท ํด๋ก 94ํ(๊ณ ์ 32) ยท ๋ฆด๋ฆฌ์ค ์์ฐ ๋์ ๋ค์ด๋ก๋ 70
2026-08-12 ์๋ ๊ฐฑ์ ยท ์ ์ฒด ์ด๋ ฅ์
docs/usage.csv. GitHub ํธ๋ํฝ ํต๊ณ๋ 14์ผ ์ฐฝ๋ง ์ ๊ณตํ๋ฏ๋ก ์ด ์ ์ฅ์๊ฐ ๋งค์ผ ์ฐ์ด ๋์ ํ๋ค.
๊ตญ๋ฆฝ์ค์๋์๊ด ์์ฅ์๋ฃ ๊ฒ์ OpenAPI ๋ฅผ Claude ๋ฑ MCP ํด๋ผ์ด์ธํธ์์ ๋ฐ๋ก ์ฐ๋ ์๋ฒ + CLI. ๋จํ๋ณธยท์จ๋ผ์ธ์๋ฃ์ ์์ง, KDC ๋ถ๋ฅ, ์ฒญ๊ตฌ๊ธฐํธ, ์๋ฌธ ์ ๊ณต ์ฌ๋ถ๋ฅผ ๊ฒ์ยท์์งํ๊ณ xlsx/csv/json/sqlite ๋ก ๋ด๋ณด๋ ๋๋ค.
์๋งค ํ๋ก์ ํธ: kci-openapi-mcp(ํ์ ๋ ผ๋ฌธยท์ธ์ฉ์ง์) ยท scienceON-mcp(KISTI ๋ฌธํ)
์ด ๋๊ตฌ๊ฐ ํน๋ณํ ์ ๊ฒฝ ์ฐ๋ ๊ฒ โ ์กฐ์ฉํ ์ ๋จ ๋ฐฉ์ง
๊ตญ๋ฆฝ์ค์๋์๊ด ๊ฒ์ API ๋ ํ ๊ฒ์์๋น 500๊ฑด๊น์ง๋ง ๋๋ ค์ค๋๋ค(๊ณต์ ์ค๋ฅ์ฝ๋ 012 DATA LIMIT 500).
๊ทธ๋ฐ๋ฐ total ์ ๊ทธ๋ณด๋ค ํฐ ๊ฐ์ ํ์ฐํ ๋ณด๊ณ ํฉ๋๋ค.
๊ต์ก๋ณต์ง: total=1,856 โ ์ค์ ๋ก ๋ฐ์ ์ ์๋ ๊ฑด 500๊ฑด
์ด ์ฌ์ค์ ๋ชจ๋ฅด๋ฉด ๋ถ๋ถ ์งํฉ์ ์ ์๋ก ์ค์ธํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋์ ๋ชจ๋ ์๋ต์
totalยทtruncatedยทcap_hit ์ ํจ๊ป ์ฃ๊ณ , ์ํ์ ๊ฑธ๋ฆฌ๋ฉด ์ฒ๋ฐฉ๊น์ง ๋ฌธ์ฅ์ผ๋ก ์๋ ค์ค๋๋ค.
| ์ ํธ | ๋ป | ์ฒ๋ฐฉ |
|---|---|---|
truncated | ์ด๋ฒ ํธ์ถ์ด total ๋ณด๋ค ์ ๊ฒ ๋ฐ์ | ๋๊ฐ max_records ๋ฅผ ์ฌ๋ฆฌ๋ฉด ํด๊ฒฐ |
cap_hit | total > 500 โ API ๊ฐ ๋ ์ ์ค | max_records ๋ก๋ ๋ถ๊ฐ (์๋ ์ฐธ์กฐ) |
meta.cap_hit_terms | ์ํ์ ๊ฑธ๋ฆฐ ๊ฒ์์ด ๋ชฉ๋ก | ๊ทธ ๊ฒ์์ด๋ง ์ธ๋ถํ |
์ํ์ ๋๊ฒจ ๋ชจ์ผ๋ ๋ฐฉ๋ฒ โ ํจ๊ป ์ฐ๋ฉด ์ ์ ์์ง์ด ๋ฉ๋๋ค
๊ต์ก๋ณต์ง/๋์(1,856๊ฑด) ๋ผ์ด๋ธ ์ค์ธก:
| ์ค์ | ํ์ | ๋น์จ | ์์ฒญ |
|---|---|---|---|
| ์ฐํ ์์ | 500 | 27% | 1 |
sort_depth=3 | 1,746 | 94% | 7 |
auto_partition=True + sort_depth=1 | 1,854 | 100% | 24 |
sort_depth ๊ฐ ๋น์ฉ ๋๋น ํจ๊ณผ๊ฐ ์๋์ ์
๋๋ค โ ๊ฐ์ ๊ฒ์์์ ์ ๋ ฌ ์์๋ง ๋ฐ๊ฟ ๋ค์ ํ๋๋ฐ,
asc ์ desc ์ ๊ต์งํฉ์ด 0๊ฑด์ด๋ผ ์ ๋ ฌ์ถ ํ๋๊ฐ ์ํ์ ์ฌ์ค์ 2๋ฐฐ๋ก ๋๋ฆฝ๋๋ค.
๋ถํ (auto_partition)๊ณผ ์ง๊ตํ๋ฏ๋ก ํจ๊ป ์ธ ์ ์์ต๋๋ค.
โ auto_partition=True โ ์๋ฒ์ธก ์ถ์ผ๋ก ์ฌ๊ท ๋ถํ
์๋ต ํ๋๋ช
์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ๋ณด๋ ๋ฐฉ์์ผ๋ก ์ค์ ๋์ํ๋ ์ถ 3๊ฐ๋ฅผ ์ฐพ์์ต๋๋ค:
category โ manageName(๋ ๋ค ์์ ๋ถํ ) โ licYn. ์ํ์ ๊ฑธ๋ฆฐ ์กฐ๊ฐ๋ง ๋ค์ ์ถ์ผ๋ก ๋ ์ชผ๊ฐ๊ณ ,
๋ถ๋ชจ ์กฐ๊ฐ๋ ํฉ์งํฉ์ ๋ฃ์ด ๋ถ์์ ํ ์ถ์ ์จ๋ ์ํด๊ฐ ๋์ง ์๊ฒ ํ์ต๋๋ค.
๊ต์ก๋ณต์ง(์ ์ฒด 7,028๊ฑด) ์ค์ธก:
| ๊น์ด | ์ถ | ํ์ | ๋น์จ | ์์ฒญ |
|---|---|---|---|---|
| โ | ๋ถํ ์์ | 500 | 7% | 1 |
| 1 | category | 2,134 | 30% | 13 |
| 2 | +manageName (๊ธฐ๋ณธ) | 3,265 | 46% | 25 |
| 3 | +licYn | 4,722 | 67% | 60 |
partition_depth(1~3)๋ก ์กฐ์ ํฉ๋๋ค. โ ๏ธ ์ ์๋ ์๋๋ฉฐ โ ๊น์ด 3์์๋ 33%๊ฐ ๋จ์ต๋๋ค โ
๋ชป ๋ฐ์ ๊ฑด์๋ meta.axes[].partition.unreachable ๋ก ๋ณด๊ณ ํฉ๋๋ค.
โก exact=True โ ํฐ๋ฐ์ดํ ๊ตฌ๋ฌธ๊ฒ์ (โ ๏ธ ๋๊ฒ ๋ชจ์ ๋๋ ์ฐ์ง ๋ง์ธ์)
total ์์ฒด๊ฐ ์ค์ด๋ค์ด(๊ต์ก๋ถํ๋ฑ 63 โ 28) ์ํ ์๋๋ก ๋ด๋ ค๊ฐ ์ ์์ต๋๋ค. ๋ค๋ง
์ฌํ์จ ์์ค์ด ํฝ๋๋ค โ ์ค์ธก ํ๊ท 47%, ์ต์
84%(๊ต์กํํ์ฑ 31 โ 5๊ฑด). ๊ตฌ๋ฌธ๊ฒ์์ ํ ํฐ
์ธ์ ์ ์๊ตฌํ๋๋ฐ ํ๊ตญ์ด ๋ณตํฉ์ด๋ ํ์ ์์ ์กฐ์ฌยท์์์ด๋ก ๊ฐ๋ผ์ง๊ธฐ ๋๋ฌธ์
๋๋ค
(๊ต์ก์ ํํ์ฑ, ์ด์ค๋ฑ๊ต์ก์ ํํ์ฑ๊ณผ). ๋ฒ๋ ค์ง ๊ฒ์ 76%๊ฐ ๊ด๋ จ ๋ฌธํ์ด์์ต๋๋ค.
โ ์ฝํผ์ค ์์ง์ ๊ธฐ๋ณธ ๊ฒ์ + contains ํ์ฒ๋ฆฌ, exact ๋ ์ ์ฒด ํ์ ๋ฅผ ์๋ ํน์ ์๋ฃ ์กฐํ์ฉ.
โ ๏ธ
year_from/contains๋ ์ด๋ฏธ ๋ฐ์ ๋ ์ฝ๋์ ๋ํ ํ์ฒ๋ฆฌ๋ผ ์ํ์ ํ์ด์ฃผ์ง ์์ต๋๋ค. ์๋ฒ์ธก ์ฐ๋ ๋ฒ์ ํํฐ๋ ํ์ธ๋์ง ์์์ต๋๋ค(11๊ฐ ํ๋ณด ๋ฌด์).
๐ด ์ ์ (2026-08-12) โ ์ด์ ํ์์ "์ ๋ ฌ์ ์กด์ฌํ์ง ์์ต๋๋ค"๋ผ๊ณ ์ ์์ผ๋ ํ๋ ธ์ต๋๋ค.
sort=ipub_year&order=asc|desc๊ฐ ๋์ํฉ๋๋ค โsort_depth๋ก ๊ตฌํํ์ต๋๋ค(์ ํ).detailSearch=true+f1/v1/and1๋ก ํ๋ ๊ฐ AND/OR/NOT ๋ ๋ฉ๋๋ค(AND+NOT=๋ถ๋ชจ๊ฒ์ฐ ํต๊ณผ) โ ์ด์ชฝ์ ์์ง ๋ฏธ๊ตฌํ์ ๋๋ค. ์์ธํ ๋ด์ฉ โ docs/NL_API_GUIDE.md ยง1-4-bยทยง1-6ยทยง3-3
์ค์น
1) Claude Code / Claude Desktop (uvx โ ๊ถ์ฅ)
{
"mcpServers": {
"nl": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "git+https://github.com/rubatoyd/nl-openapi-mcp", "nl-mcp"],
"env": { "NL_API_KEY": "๋ฐ๊ธ๋ฐ์_์ธ์ฆํค" }
}
}
}
2) Claude Desktop .mcpb ์ํด๋ฆญ
Releases ์์ ๋ด๋ ค๋ฐ์ ์คํํฉ๋๋ค.
Pythonยทuv ๊ฐ ์๋ ํ๊ฒฝ์ด๋ฉด OS๋ณ ์์ฒด์๊ฒฐ ๋ฒ๋ค(-win-x64 / -macos-arm64 / -linux-x64)์ ์ฐ์ธ์.
3) ๋ก์ปฌ ๊ฐ๋ฐ
git clone https://github.com/rubatoyd/nl-openapi-mcp
cd nl-openapi-mcp
uv sync
uv run pytest -q
ํด๋ผ์ฐ๋ ๋๊ธฐํ ํด๋(OneDrive ๋ฑ)์์ ์์ ํ๋ค๋ฉด venv ๋ฅผ ํด๋ ๋ฐ์ ๋์ธ์:
UV_PROJECT_ENVIRONMENT=~/.venvs/nl-openapi-mcp
4) ๋ค๋ฅธ MCP ํด๋ผ์ด์ธํธ
ํ์ค stdio MCP ์๋ฒ์ด๋ฏ๋ก MCP ๋ฅผ ์ง์ํ๋ ์์ด์ ํธ๋ฉด ๊ทธ๋๋ก ๋ถ์ต๋๋ค โ Cursor ยท Windsurf ยท
Cline ยท Zed ยท VS Code Copilot(agent mode) ยท OpenAI Agents SDK ยท ์์ฒด ํด๋ผ์ด์ธํธ ๋ฑ.
์ command/args/env 3์์๋ฅผ ๊ฐ ํด๋ผ์ด์ธํธ ์ค์ ์ ์ฎ๊ธฐ๋ฉด ๋ฉ๋๋ค.
์ ์ก ๋ฐฉ์ โ stdio(๊ธฐ๋ณธ) ยท SSE ยท Streamable HTTP
๋ก์ปฌ ์๋ธํ๋ก์ธ์ค๋ฟ ์๋๋ผ HTTP ๋ก๋ ๋์ธ ์ ์์ต๋๋ค. ์๊ฒฉ ํธ์คํ ์ด๋ stdio ๋ฅผ ๋ชป ์ฐ๋ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ ๊ฒฝ๋ก์ ๋๋ค.
nl-mcp # stdio (๊ธฐ๋ณธ)
nl-mcp --transport streamable-http # http://127.0.0.1:8000/mcp
nl-mcp --transport sse --port 9000 # http://127.0.0.1:9000/sse
ํ๊ฒฝ๋ณ์: NL_MCP_TRANSPORT ยท NL_MCP_HOST ยท NL_MCP_PORT.
โ ๏ธ HTTP ์ ์ก์๋ ์ธ์ฆ์ด ์์ต๋๋ค. ๊ธฐ๋ณธ ๋ฐ์ธ๋๋ ๋ฃจํ๋ฐฑ(
127.0.0.1)์ด๋ผ ๊ฐ์ PC ์์๋ง ์ ๊ทผ๋ฉ๋๋ค.--host 0.0.0.0์ผ๋ก ์ธ๋ถ์ ์ด๋ฉด ์ธ์ฆํค๋ฅผ ํ์ ์๋ฒ๋ฅผ ๊ทธ๋๋ก ๊ณต๊ฐํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค โ ์ ๋ขฐ๋ ๋ง์์๋ง ์ฐ์ธ์. ์๋ฒ๋ ๊ธฐ๋ ์ ๊ฒฝ๊ณ ๋ฅผ ์ฐ์ต๋๋ค.
Claude ์ฑ ์์์ ๊ฒ์ํด ์ค์นํ ์๋ ์์ต๋๋ค. ๊ณต์ MCP ๋ ์ง์คํธ๋ฆฌ ๋ฑ์ฌ์ Claude Desktop ์ธ์ฑ ์ปค๋ฅํฐ ๋๋ ํฐ๋ฆฌ๋ ๋ณ๊ฐ์ด๊ณ ์๋ ๋๊ธฐํ๋์ง ์์ต๋๋ค. ์ ์ค์น ๋ฐฉ๋ฒ ์ค ํ๋๋ฅผ ์ฐ์ธ์.
์ธ์ฆํค
www.nl.go.kr ์คํAPI ์ ์ฒญ์ผ๋ก ๋ฐ๊ธ๋ฐ์ NL_API_KEY ๋ก ์ค์ ํฉ๋๋ค.
ํ ํฐ ๋ฐ๊ธยทAES ์ํธํยท๊ณต์ธIP ๋ฑ๋ก์ด ํ์ ์์ต๋๋ค(ํ๋ฌธ key ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ).
cp .env.example .env # NL_API_KEY ๋ฅผ ์ฑ์ ๋ฃ์ผ์ธ์ (.env ๋ gitignore ๋ฉ๋๋ค)
| ํ๊ฒฝ๋ณ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
NL_API_KEY | (ํ์) | ๊ตญ๋ฆฝ์ค์๋์๊ด ์คํAPI ์ธ์ฆํค |
NL_OS_TRUST | 1 | ๊ต์ก๋งยท์ฌ๋ด๋ง SSL ์ธํฐ์
์
๋์(OS ์ ๋ขฐ์ ์ฅ์ ์ฌ์ฉ). 0 ์ด๋ฉด ๋นํ์ฑ |
ํ๊ตยท๊ต์ก์ฒญยท์ฌ๋ด๋ง์ ์์ฒด์๋ช ๋ฃจํธ CA๋ก TLS๋ฅผ ๊ฐ๋ก์ฑ๋๋ค. ์ด ๋๊ตฌ๋ ๊ฒ์ฆ์ ๋์ง ์๊ณ
truststore๋ก OS ์ ๋ขฐ์ ์ฅ์๋ฅผ ์ฌ์ฉํด ํต๊ณผํฉ๋๋ค.
MCP ๋๊ตฌ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
nl_status | ์ธ์ฆํค ์ ํจ์ฑ + API ์ค์ ์๋ณต 1ํ ์ ๊ฒ |
nl_search | ์์ฅ์๋ฃ ๊ฒ์ (totalยทtruncatedยทcap_hit ๋๋ฐ) |
nl_collect | ๊ฒ์์ด ํฉ์งํฉ ์์ง โ ํ์ผ ์ ์ฅ. save=false ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ง |
์์
"๊ตญ๋ฆฝ์ค์๋์๊ด์์ '๊ต์ก๋ถํ๋ฑ', '๊ต์ก๊ฒฉ์ฐจ', 'ํ๋ ฅ๊ฒฉ์ฐจ' ๊ด๋ จ ๋จํ๋ณธ์ ๋ชจ์์ xlsx๋ก ์ ์ฅํด์ค"
nl_collect ๊ฐ ์ธ ๊ฒ์์ด๋ฅผ ๊ฐ๊ฐ ์กฐํํด id ๊ธฐ์ค์ผ๋ก ํฉ์งํฉ์ ๋ง๋ค๊ณ , ์ํ์ ๊ฑธ๋ฆฐ ๊ฒ์์ด๊ฐ
์์ผ๋ฉด meta.cap_hit_terms ๋ก ์ง๋ชฉํฉ๋๋ค.
์ถ๋ ฅ ํ์ผ๋ช ์ ์ ๊ทํ๋ฉ๋๋ค.
name์ ์ง์ ํ์ง ์์ผ๋ฉด ๊ฒ์์ด๊ฐ ๊ทธ๋๋ก ํ์ผ๋ช ์ด ๋๋ฏ๋ก, ๊ฒฝ๋ก ๊ตฌ๋ถ์ยท..ยท์๋ ๊ธ์ง๋ฌธ์๋ ์ ๊ฑฐ๋๊ณ ๊ฒฐ๊ณผ๋ ํญ์out_dir์์๋ง ์ ์ฅ๋ฉ๋๋ค. ํ๊ธ ํ์ผ๋ช ์ ๊ทธ๋๋ก ๋ณด์กด๋ฉ๋๋ค.
CLI
nl status
nl search ๊ต์ก๋ถํ๋ฑ --category ๋์ --rows 20
nl collect --terms ๊ต์ก๋ถํ๋ฑ ๊ต์ก๊ฒฉ์ฐจ ํ๋ ฅ๊ฒฉ์ฐจ --category ๋์ --format xlsx json
# 500 ์ํ์ ๋๊ฒจ ๋ชจ์ผ๊ธฐ โ ์ ๋ ฌ ๋ค์ง๊ธฐ๊ฐ ๊ฐ์ฅ ๊ฐ์ธ๋ค (7์์ฒญ์ 94%)
nl collect --kwd ๊ต์ก๋ณต์ง --category ๋์ --sort-depth 3 --format xlsx
# ๋ถํ ๊ณผ ํจ๊ป ์ฐ๋ฉด ์ ์ ์์ง (์ค์ธก 100%)
nl collect --kwd ๊ต์ก๋ณต์ง --category ๋์ --auto-partition --sort-depth 1 --format xlsx
์๋ต ํ๋
์ ๊ทํ 25๊ฐ ์ปฌ๋ผ + ์๋ณธ 24๊ฐ ํ๋(raw) ๋ณด์กด. ์ ์ฒด ํ์ ๊ฒฐ์ธก๋ฅ ์
docs/NL_API_GUIDE.md ยง2 ์ฐธ์กฐ.
์ฃผ์ํ ํ๋ 2๊ฐ์ง โ ์ด๋ฆ์ด โฆYn ์ด์ง๋ง ๋ถ๋ฆฌ์ธ์ด ์๋๋๋ค:
docYnโdoc_type:NL_VIEWERยทLD_VIEWERยทFILEยทLINKยทNlicYnโlic_code:LยทFยทSยทDยทNยทY
์๋ฌธ ๋ณด์ ํ์ ์ Holding.has_fulltext() ๋ฅผ ์ฐ์ธ์("N"ยท๋น๊ฐ๋ง ๊ฑฐ์ง).
๊ฒ์ฆ ์ํ
- โ ์๋ต ์คํค๋ง 24๊ฐ ํ๋ โ ์ค์๋ต 1,124๊ฑด ์ ์ ์ง๊ณ๋ก ํ์
- โ 500๊ฑด ์ํ โ ๊ณต์ ์ค๋ฅ์ฝ๋ + ์ค์ ์์ง ๋ก๊ทธ + ์คํ์ ๊ธฐ์ค๊น์ง ์ค์ธก
- โ
ํธ์ถ ๊ท๊ฒฉ ๋ผ์ด๋ธ ์ ์ ๊ฒ์ฆ โ
srchTarget์ง์/ํด๋ฐฑ,category12์ข ,sort์์ธ ํ๋๋ช ,ipub_year์ฐ๋ ํํฐ, f-์ฌ๋กฏ ๋ถ๋ฆฌ์ธ, ์ค๋ฅ ๋ดํฌ, 0๊ฑด ์๋ต ํํ.scripts/probe_api.py๋ก ์ฌํ ๊ฐ๋ฅ - โ ์คํ๋ผ์ธ ํ๊ท 186๊ฑด ยท MCP stdio ํธ๋์ ฐ์ดํฌ ยท CI ์ฝ๋ ์คํํธ ์ค๋ชจํฌ ยท ์์ฒด์๊ฒฐ ๋ฐ์ด๋๋ฆฌ ํด๋ฆฐ ํ๊ฒฝ ๊ฒ์ฆ
- โ ๏ธ ์๋ฒ์ธก ์ฐ๋ ๋ฒ์(from~to) ํํฐ๋ง ๋ฏธํ์ธ โ ๋จ์ผ ์ฐ๋(
ipub_year)๋ ๋์ํฉ๋๋ค
๋ผ์ด์ ์ค
MIT