kr-elections-mcp
MCP server for South Korean election research, providing tools to search candidates, retrieve election results, and lookup campaign booklet texts using NEC open data and the krpoltext dataset.
README
South Korean Election MCP (kr-elections-mcp)
South Korean Election MCP (kr-elections-mcp) is a local Python FastMCP server for South Korean election research. It combines NEC open data, normalized result adapters, and krpoltext text lookups into task-oriented MCP tools.
This repository is composite-first. It does not mirror every raw NEC endpoint as a public MCP tool. Instead, it focuses on higher-value workflows such as candidate packets, district summaries, election overviews, diagnostics, and safe text lookups.
What It Provides
- Candidate search and profile retrieval
- Candidate policy retrieval when NEC coverage is available
- District-level election results and summaries
- Party vote-share history and election overviews
krpoltexttext lookup for campaign booklet corpus rows- Composite packet assembly across NEC, results, and
krpoltexttext - NEC API diagnostics for local BYOK usage
Quick Start
1. Install the CLI
Requires Python 3.11+.
Recommended for most users:
pipx install .
pipx keeps the CLI isolated and makes it easier to point MCP clients at a stable kr-elections-mcp command.
If you prefer plain pip:
python -m pip install .
For development from a repository checkout:
python -m venv .venv
# activate the virtual environment for your shell
python -m pip install -r requirements.txt
python -m pip install -e .
This project is currently distributed as a Python package, not an npm package. If your MCP client is JavaScript- or Node-based, install the Python CLI first and then reference kr-elections-mcp from the client config below.
2. Apply for NEC API access
This project uses a BYOK model. Each user must apply for the relevant NEC OpenAPI products through the Public Data Portal (data.go.kr).
The Public Data Portal notes that encoded and decoded service keys can behave differently depending on API environment or invocation conditions. This server accepts both forms.
See:
3. Store the key securely
Recommended:
kr-elections-mcp setup-key
setup-key accepts both encoded and decoded NEC service keys. You can store one or both.
Important behavior:
- If only
NEC_API_KEY_DECODEDis present, the server derives the encoded variant automatically. - Request order is always decoded first, then encoded.
- Legacy
NEC_API_KEYstill works as a fallback.
Useful commands:
kr-elections-mcp show-key-source
kr-elections-mcp clear-key
4. Run the MCP server
kr-elections-mcp run
MCP Client Example
After installation, your MCP client should launch the Python-installed CLI, not an npm wrapper.
{
"mcpServers": {
"south-korean-election": {
"command": "kr-elections-mcp",
"args": ["run"]
}
}
}
If you do not want OS keyring storage, you can provide the key in the MCP client environment instead:
{
"mcpServers": {
"south-korean-election": {
"command": "kr-elections-mcp",
"args": ["run"],
"env": {
"NEC_API_KEY_DECODED": "YOUR_DECODED_KEY"
}
}
}
}
NEC_API_KEY_ENCODED is not required if the decoded key is already available.
API Key Storage Rules
Key lookup priority is:
- Process environment or MCP client
env - OS keyring
.envdevelopment fallback
Within each source, the server prefers NEC_API_KEY_DECODED and NEC_API_KEY_ENCODED, then falls back to legacy NEC_API_KEY.
Recommended for public users:
- Use
kr-elections-mcp setup-keywhen possible. - Keep keys out of chat, screenshots, and Git commits.
- Treat
.envas a development-only fallback. - If you intentionally use
.env, pass it explicitly with--env-file .env. - In many environments,
NEC_API_KEY_DECODEDalone is enough.
Source Checkout Fallback
If you are running directly from a repository checkout instead of an installed package, the legacy commands still work:
python server.py setup-key
python server.py show-key-source
python server.py run
If you intentionally want to load a local dotenv file, pass it explicitly:
kr-elections-mcp run --env-file .env
python server.py run --env-file .env
Tools
Core tools:
list_electionslist_districtslist_partiessearch_candidatesget_candidate_profileget_candidate_policiesget_district_resultsget_district_summaryget_party_vote_share_historyget_election_overviewassemble_candidate_packetdiagnose_core_api_access
Additional tools:
diagnose_full_api_accessget_krpoltext_textget_krpoltext_metamatch_krpoltext_candidate
krpoltext Text Support
This repository does not OCR live NEC booklet PDFs on demand.
Current behavior:
get_krpoltext_textcan match on candidate name plus optional year, office, district, and party hints.- It can also match directly on booklet
code. get_krpoltext_metareturns structured campaign booklet metadata without the long booklet text body.- The metadata tool preserves merged candidate bio fields such as
giho,birthday,age,job*,edu*, andcareer*when the upstream dataset provides them. match_krpoltext_candidateresolves an NEC candidate first, then rankskrpoltextrows using election scope plus stronger personal identifiers.- Same-election same-district same-name collisions remain ambiguous unless a stronger personal identifier uniquely matches.
- The adapter now uses the current
krpoltextdata manifest under/data/index.json, falls back to/data/metadata.jsonwhen needed, and resolves thecampaign_bookletresource. - It understands both legacy
download_urlentries and newerdownload_urlsmaps fromkrpoltext0.2.0, including OSF-managed artifact links. - Enriched NEC linkage fields such as
huboidare preserved when the upstream corpus provides them, andmatch_krpoltext_candidatecan use them as strong identifiers. - Runtime installs now include
pyarrow, so enriched Parquet artifacts can be preferred by default while CSV metadata and fallback URLs remain supported. - Legacy text fetches stay on configured
krpoltexthosts, and dataset artifact fetches accept the trusted OSF-managed download hosts used by the current manifest. - When text is available in the campaign booklet corpus, the tool returns the dataset-backed text record and corpus metadata such as
code,party_name, andpage_countwhen present. - This public repository does not expose live NEC booklet discovery, URL derivation, or PDF download.
Example metadata lookup for Moon Jae-in in the 2017 presidential election:
get_krpoltext_meta(
candidate_name="문재인",
election_year=2017,
office_name="president",
district_name="전국 대한민국",
party_name="더불어민주당",
limit=3
)
Example response shape:
{
"items": [
{
"record_id": "ECM0120170001_0001S",
"code": "ECM0120170001_0001S",
"candidate_name": "문재인",
"office_name": "president",
"election_year": 2017,
"district_name": "전국 대한민국",
"giho": "1",
"party_name": "더불어민주당",
"birthday": "1953-01-24",
"age": 64,
"edu": "경희대학교 법률학과 졸업",
"career1": "(전)더불어민주당 당대표",
"career2": "(전)제19대 국회의원",
"page_count": 15,
"has_text": true
}
],
"warnings": []
}
Example conservative NEC-to-krpoltext match:
match_krpoltext_candidate(
candidate_name="문재인",
sg_id="20170509",
sg_typecode="1",
district_name="전국 대한민국",
limit=5
)
Example response shape:
{
"status": "resolved",
"message": "Resolved krpoltext metadata row from NEC election, office, district, and name context.",
"item": {
"code": "ECM0120170001_0001S",
"candidate_name": "문재인",
"district_name": "전국 대한민국",
"giho": "1",
"birthday": "1953-01-24",
"age": 64,
"match_method": "name+year+office+district+party+giho+birthday+age+sex+education+job+career",
"match_confidence": 1.0
},
"warnings": [],
"errors": []
}
The examples above use a real 2017 presidential-election row from the managed campaign booklet corpus.
Resources
resource://nec/electionsresource://nec/districts/{sg_id}/{sg_typecode}resource://nec/parties/{sg_id}/{sg_typecode}
Documentation
- API Access Guide (Korean)
- Source Status (Korean)
- Architecture (Korean)
- Data Sources (Korean)
- Examples (Korean)
- Tool Matrix (Korean)
- krpoltext Matching Guide (Korean)
- Operational Security Notes (Korean)
How to Cite
If you use this software in research, cite the software record or export citation metadata from CITATION.cff.
- DOI: 10.5281/zenodo.19490046
- Citation metadata: CITATION.cff
Example citation:
Lim T (2026). kr-elections-mcp. doi:10.5281/zenodo.19490046, Python package version 0.1.0, https://github.com/taehyun-lim/kr-elections-mcp.
Example BibTeX:
@Manual{Lim2026krElectionsMcp,
title = {kr-elections-mcp},
author = {Tae Hyun Lim},
year = {2026},
doi = {10.5281/zenodo.19490046},
url = {https://github.com/taehyun-lim/kr-elections-mcp},
note = {Python package version 0.1.0},
}
Testing
Tests are designed to run with mocks and stubs even without a live NEC API key.
pytest
The source-adapter tests cover krpoltext manifest resolution, trusted-host handling, and campaign booklet corpus lookups.
Limitations
- NEC policy coverage is incomplete and depends on service support by election and office.
- Live NEC API access still depends on each user's approved
data.go.kraccess. - Result coverage can differ by source and historical election availability.
krpoltextsupport depends on the current external dataset manifest and does not perform live OCR over NEC booklet files.
License
This project is released under the MIT License.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。