Kr Elections Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Kr Elections Mcp (Agent Skill) and scored it 87/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 3 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
krpoltext text lookup for campaign booklet corpus rowskrpoltext textRequires 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.
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:
Recommended:
kr-elections-mcp setup-keysetup-key accepts both encoded and decoded NEC service keys. You can store one or both.
Important behavior:
NEC_API_KEY_DECODED is present, the server derives the encoded variant automatically.NEC_API_KEY still works as a fallback.Useful commands:
kr-elections-mcp show-key-source
kr-elections-mcp clear-keykr-elections-mcp runAfter 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.
Key lookup priority is:
env.env development fallbackWithin 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:
kr-elections-mcp setup-key when possible..env as a development-only fallback..env, pass it explicitly with --env-file .env.NEC_API_KEY_DECODED alone is enough.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 runIf 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 .envCore tools:
list_electionslist_districtslist_partiessearch_candidatesget_candidate_profileget_candidate_policiesget_district_resultsget_district_summaryget_party_vote_share_historyget_election_overviewassemble_candidate_packetdiagnose_core_api_accessAdditional tools:
diagnose_full_api_accessget_krpoltext_textget_krpoltext_metamatch_krpoltext_candidatekrpoltext Text SupportThis repository does not OCR live NEC booklet PDFs on demand.
Current behavior:
get_krpoltext_text can match on candidate name plus optional year, office, district, and party hints.code.get_krpoltext_meta returns structured campaign booklet metadata without the long booklet text body.giho, birthday, age, job*, edu*, and career* when the upstream dataset provides them.match_krpoltext_candidate resolves an NEC candidate first, then ranks krpoltext rows using election scope plus stronger personal identifiers.krpoltext data manifest under /data/index.json, falls back to /data/metadata.json when needed, and resolves the campaign_booklet resource.download_url entries and newer download_urls maps from krpoltext 0.2.0, including OSF-managed artifact links.huboid are preserved when the upstream corpus provides them, and match_krpoltext_candidate can use them as strong identifiers.pyarrow, so enriched Parquet artifacts can be preferred by default while CSV metadata and fallback URLs remain supported.krpoltext hosts, and dataset artifact fetches accept the trusted OSF-managed download hosts used by the current manifest.code, party_name, and page_count when present.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.
resource://nec/electionsresource://nec/districts/{sg_id}/{sg_typecode}resource://nec/parties/{sg_id}/{sg_typecode}If you use this software in research, cite the software record or export citation metadata from 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},
}Tests are designed to run with mocks and stubs even without a live NEC API key.
pytestThe source-adapter tests cover krpoltext manifest resolution, trusted-host handling, and campaign booklet corpus lookups.
data.go.kr access.krpoltext support depends on the current external dataset manifest and does not perform live OCR over NEC booklet files.This project is released under the MIT License.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.