korean-people-persona
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@korean-people-personaFind a Korean persona who loves hiking and is in their 20s"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
korean-people-persona
A collection of tools for converting and searching the HuggingFace nvidia/Nemotron-Personas-Korea dataset (approx. 1 million rows, 9 parquet files) using SQLite.
Overview
Source: NVIDIA, Nemotron-Personas-Korea — https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea
License: Follows the license terms on the original dataset page
DB File:
database/persona.dbOriginal parquet:
data/train-*-of-*.parquetTables:
persona(main) +persona_fts(FTS5 external content index)Target SQLite: 3.37+ (uses FTS5, STRICT tables, JSON1)
Python: 3.10 or higher (3.11+ recommended)
Dependencies:
pyarrow >= 15.0,huggingface_hub >= 0.24(seerequirements.txt)Disk Space: Approx. 5 GB (parquet ~2GB + DB ~3GB)
Related MCP server: Legal Search MCP
Data Source
Item | Value |
Repository | |
Files |
|
Rows per file | Approx. 111,112 |
Total rows | 1,000,000 |
Missing values | 0 in all columns (NOT NULL guaranteed) |
| All |
| Python |
Folder Structure
korean-people-persona/
├── data/ # 원본 parquet (gitignore — 약 2GB)
│ └── train-*-of-*.parquet
├── database/ # 생성된 SQLite (gitignore — 약 3GB)
│ └── persona.db
├── src/
│ ├── convert/ # parquet → SQLite 변환기
│ │ ├── __init__.py
│ │ └── __main__.py
│ └── mcp_server/ # (예정) MCP 서버
├── build.sh / build.bat / build.ps1
├── requirements.txt
└── README.mddata/ and database/ are excluded via .gitignore due to their large size.
Downloading the Dataset
Choose one of the three methods. The resulting files must be placed in the data/ folder as train-*-of-*.parquet.
1) Conversion Script Option (Recommended)
Automatically fetches if the src/convert package is missing:
pip install huggingface_hub pyarrow
PYTHONPATH=src python -m convert --download # 없을 때만 받음
PYTHONPATH=src python -m convert --download --force-download # 항상 재다운로드2) Using huggingface-cli directly
pip install huggingface_hub
huggingface-cli download nvidia/Nemotron-Personas-Korea \
--repo-type dataset \
--include "train-*-of-*.parquet" \
--local-dir ./data3) git lfs clone
git lfs install
git clone https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea
mv Nemotron-Personas-Korea/train-*.parquet ./data/Authentication: For private or gated models,
huggingface-cli loginor theHF_TOKENenvironment variable is required. This dataset (as of the public release) can be downloaded without authentication.
Size: Total of 9 parquet files is approx. 1~2 GB.
Main Table persona
CREATE TABLE persona (
uuid TEXT PRIMARY KEY, -- 32자 hex 문자열 (대시 없음)
-- 페르소나 서술 (긴 한국어 텍스트) ----------------------------------------------
persona TEXT NOT NULL, -- 핵심 1~2문장 요약
professional_persona TEXT NOT NULL, -- 직업/업무 페르소나
sports_persona TEXT NOT NULL, -- 스포츠/운동 페르소나
arts_persona TEXT NOT NULL, -- 예술/문화 페르소나
travel_persona TEXT NOT NULL, -- 여행 페르소나
culinary_persona TEXT NOT NULL, -- 식문화/요리 페르소나
family_persona TEXT NOT NULL, -- 가족 관계 페르소나
cultural_background TEXT NOT NULL, -- 문화·성장 배경 서술
skills_and_expertise TEXT NOT NULL, -- 보유 기술/전문성 서술
hobbies_and_interests TEXT NOT NULL, -- 취미·관심사 서술
career_goals_and_ambitions TEXT NOT NULL, -- 향후 목표/포부
-- 리스트 (JSON 배열로 저장) -----------------------------------------------------
skills_and_expertise_list TEXT NOT NULL CHECK(json_valid(skills_and_expertise_list)), -- 스킬 키워드 JSON 배열
hobbies_and_interests_list TEXT NOT NULL CHECK(json_valid(hobbies_and_interests_list)), -- 취미 키워드 JSON 배열
-- 인구통계 ---------------------------------------------------------------------
sex TEXT NOT NULL, -- 성별: 남자 / 여자
age INTEGER NOT NULL CHECK(age >= 0), -- 나이 (정수)
marital_status TEXT NOT NULL, -- 결혼상태 (4종: 미혼/기혼/이혼/사별 등)
military_status TEXT NOT NULL, -- 병역상태 (군필/해당없음 등)
family_type TEXT NOT NULL, -- 가구 유형 (39종: 1인 가구, 배우자와 자녀 등)
housing_type TEXT NOT NULL, -- 주거 형태 (6종: 아파트, 단독주택 등)
education_level TEXT NOT NULL, -- 최종 학력 (7종: 초등학교 ~ 대학원)
bachelors_field TEXT NOT NULL, -- 학사 전공 분야
occupation TEXT NOT NULL, -- 직업 (자유 텍스트)
district TEXT NOT NULL, -- 시군구 (예: 강남-서초)
province TEXT NOT NULL, -- 시도 (17종)
country TEXT NOT NULL DEFAULT '대한민국' -- 국가 (단일값: 대한민국)
) STRICT;Indexes
Name | Columns | Purpose |
|
| Sex/age distribution query |
|
| Regional filter |
|
| Education/occupation analysis |
|
| Household/marital analysis |
Column Definitions
Column | Description | Example |
| 32-char hex string (no dashes). PK |
|
| Core 1-2 sentence summary |
|
| Detailed persona by domain (paragraph length) | Occupation/Sports/Arts/Travel/Food/Family |
| Cultural/growth background description | |
| Skills description | |
| Keyword list for the above (JSON array) |
|
| Hobbies/interests description | |
| Keyword list for the above (JSON array) |
|
| Future goals | |
|
| |
| Integer | |
| 4 types |
|
| 2 types |
|
| 39 types |
|
| 6 types |
|
| 7 types |
|
| Bachelor's major field | |
| Occupation (free text) | |
| City/County/District |
|
| Province/City |
|
| Country |
|
Full-Text Search — persona_fts (FTS5)
Indexes 10 long Korean descriptive columns using the external content method.
CREATE VIRTUAL TABLE persona_fts USING fts5(
professional_persona,
sports_persona,
arts_persona,
travel_persona,
culinary_persona,
family_persona,
cultural_background,
skills_and_expertise,
hobbies_and_interests,
career_goals_and_ambitions,
content='persona',
content_rowid='rowid',
tokenize='unicode61 remove_diacritics 2',
prefix='2 3 4'
);Tokenizer: unicode61 + 2/3/4 character prefix index. For Korean particle handling, prefix matching like hiking* is recommended during search. If morphological analysis is required, replace with a custom tokenizer based on mecab-ko / kiwi.
FTS Synchronization: Since the dataset is static, build once with INSERT INTO persona_fts(rowid, ...) SELECT .... Add triggers if changes are made.
AI Agent Utilization (MCP Server)
This repository provides an MCP (Model Context Protocol) server, allowing MCP-compatible agents like Claude Desktop, Cursor, and Cline to directly search and sample data.
Execution
PYTHONPATH=src python -m mcp_server # stdio 서버 시작Registration by Agent
All examples must replace the absolute path to the repository
/abs/path/to/korean-people-personawith your own environment path. If you created a virtual environment (.venv), specifying thecommandas the Python inside the venv avoids dependency conflicts. (e.g., macOS/Linux/abs/path/.venv/bin/python, WindowsC:/abs/path/.venv/Scripts/python.exe)
Claude Desktop
Config file location:
OS | Path |
macOS |
|
Windows |
|
Linux |
|
Or via the app menu: Settings → Developer → Edit Config.
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": {
"PYTHONPATH": "/abs/path/to/korean-people-persona/src",
"PYTHONIOENCODING": "utf-8"
}
}
}
}After saving, restart Claude Desktop → verify 5 tools appear in the hammer (🔨) icon at the bottom right of the chat window.
Claude Code (CLI)
Register in one line via CLI command:
claude mcp add korean-persona python -m mcp_server \
-e PYTHONPATH=/abs/path/to/korean-people-persona/src \
-e PYTHONIOENCODING=utf-8Or write directly to .mcp.json in the project root or user settings ~/.claude/settings.json:
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
}
}
}Verification: claude mcp list → After activation, tools can be called via the /mcp slash command.
Cursor
Project-specific .cursor/mcp.json or global user ~/.cursor/mcp.json:
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
}
}
}Or use the Settings → MCP → Add new MCP Server UI. After restarting Cursor, call with @korean-persona.
ChatGPT (Developer Mode / Connectors)
ChatGPT's MCP integration operates based on HTTP/SSE transport (remote connector). Since this server is a stdio server, it cannot be registered as-is; it must be wrapped with an HTTP adapter.
Run the server with the
mcpSDK's HTTP transport:PYTHONPATH=src python -m mcp_server --transport sse --port 8765(Currently, this repository's
server.pyonly calls stdio. To use HTTP/SSE mode, you need to add a branch formcp.run(transport="sse", port=8765).)Expose externally via ngrok / Cloudflare Tunnel, etc.:
ngrok http 8765ChatGPT → Settings → Connectors → Developer mode → Add custom connector
URL:
https://<ngrok>/sseAuthentication: Add Bearer token header if necessary (
MCP_AUTH_TOKEN)
In a new chat, activate the connector in the Tools menu to call tools.
Security Warning: Since ChatGPT connectors expose tools outside the model, ensure the public URL is protected by authentication. For local-only use, we recommend using stdio-based Claude Desktop / Cursor.
Gemini CLI
Google gemini-cli user settings ~/.gemini/settings.json:
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" },
"cwd": "/abs/path/to/korean-people-persona"
}
}
}Verification: gemini mcp list (or /mcp command within CLI) → tools are automatically exposed.
Common Troubleshooting
Symptom | Cause / Solution |
Tools not visible | Forgot to restart the app. Claude Desktop requires a full exit (including tray icon) |
| Check if |
Korean text garbled | Add |
| Use absolute path for |
Permission error | Path spaces on Windows → use quotes or change path |
Exposed Tools
Tool | Description |
| FTS5 free-text search + demographic filter combination (BM25 sorted) |
| Retrieve full single persona by uuid |
| Conditional random sampling |
| Demographic GROUP BY COUNT |
| Full dataset statistics and available column guide |
Agent Utilization Samples
1) Marketing Interview Simulation
"Sample 10 women aged 60+ who enjoy hiking, and simulate their reactions to the ad copy for a newly released knee brace."
Agent workflow:
search_persona(query="hiking*", filters={"sex":"female","age_min":60}, limit=10, full=True)Inject each persona into the system prompt → generate 1 response per person evaluating the ad copy
Summarize insights after response clustering
2) Region-based Character Casting
"Find a persona of a self-employed person in their 50s living in Yeongdo-gu, Busan, and organize it for use as a protagonist in a short story."
search_persona(
filters={"province":"부산", "district_like":"%영도%",
"age_min":50, "age_max":59,
"occupation_like":"%자영%"},
limit=5, full=True
)3) Policy Impact Analysis
"Analyze the distribution to see which province has the highest number of single-person households aged 70+ whose highest level of education is elementary school."
aggregate(
group_by=["province"],
filters={"education_level":"초등학교", "age_min":70,
"family_type_like":"%혼자%"},
limit=20
)4) Semantic Search + Citation
"Find a persona who grew up in a rural area and has grandchildren, and provide it along with a citation of their cultural_background."
search_persona(
query='"농촌" AND 손주*',
fields=["cultural_background", "family_persona"],
limit=5, full=True
)5) Synthetic Survey
"Stratified sample 100 people proportional to the national population distribution, then ask each of them, 'Do you agree with the introduction of a 4-day work week?'"
aggregate(group_by=["province","sex","age"])→ calculate distribution ratiosCall
sample_personaaccording to the ratios for each province×sex×age groupRequest 1:1 responses from the LLM for each persona
Aggregate results → calculate weighted approval/disapproval distribution
Direct Use (Code)
Call directly from Python without MCP:
import sys; sys.path.insert(0, "src")
from mcp_server import tools
tools.stats()
tools.search_persona(query="용접*", filters={"sex":"남자"}, limit=5)
tools.sample_persona(filters={"province":"제주"}, n=3, full=True)Direct SQL Query
-- 1) 등산을 좋아하고 트로트 관련 언급이 있는 60대 여성
SELECT p.uuid, p.age, p.province, p.occupation
FROM persona_fts f
JOIN persona p ON p.rowid = f.rowid
WHERE persona_fts MATCH '등산* AND 트로트*'
AND p.sex = '여자' AND p.age BETWEEN 60 AND 79
ORDER BY bm25(persona_fts) LIMIT 20;
-- 2) 특정 컬럼 검색 + 스니펫
SELECT p.uuid, snippet(persona_fts, 7, '<b>', '</b>', '...', 10) AS hit
FROM persona_fts f JOIN persona p ON p.rowid = f.rowid
WHERE f.skills_and_expertise MATCH '용접*' LIMIT 10;
-- 3) JSON 리스트 펼치기
SELECT p.uuid, j.value AS hobby
FROM persona p, json_each(p.hobbies_and_interests_list) j
WHERE j.value LIKE '%낚시%' LIMIT 10;
-- 4) 인구통계 분포
SELECT province, sex, COUNT(*) cnt
FROM persona GROUP BY province, sex ORDER BY cnt DESC;PRAGMA Settings (Loading/Operation)
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA temp_store = MEMORY;
PRAGMA cache_size = -262144; -- 256MBBuild Procedure
One-line Build (Recommended)
Wrapper scripts for each OS automatically create a virtual environment → install dependencies → download → convert.
Platform | Command |
Linux / macOS |
|
Windows (cmd) |
|
Windows (PowerShell) |
|
Re-download options are passed identically:
./build.sh --force-download
build.bat --force-download
.\build.ps1 --force-downloadIf you get an execution policy error in PowerShell:
PowerShell -ExecutionPolicy Bypass -File .\build.ps1
Manual Execution
python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows: .venv\Scripts\activate
pip install -r requirements.txt
PYTHONPATH=src python -m convert [--download] [--force-download]Internal processing:
(Optional)
--downloadfetches missing parquet files from HuggingFaceCreate new
persona.db(deletes existing file)Apply PRAGMA settings + create schema/indexes
Sequentially read 9 parquet files, normalize row-by-row, and load via
executemany(transaction unit: 1 file)*_listcolumns converted viaast.literal_eval→json.dumps(ensure_ascii=False)Create FTS5 virtual table + build once with
INSERT ... SELECTINSERT INTO persona_fts(persona_fts) VALUES('optimize')followed byANALYZEExit after WAL checkpoint
Disk Estimation
Main table + indexes: approx. 1.5 ~ 2.5 GB
FTS5 including prefix: additional 1 ~ 3 GB
Total expected approx. 3 ~ 5 GB (updated after actual loading).
This server cannot be deployed
Maintenance
Related MCP Connectors
Agent-native MCP server over 49M+ US public and government records, privacy-first, always current.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Pocket Agent (aipocketagent.com) MCP server — read tools for personas, apps, and product info.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server providing access to 1M synthetic Korean personas based on KOSIS statistics, enabling persona sampling, search, and analysis via natural language queries.6 npmMIT
- FlicenseAqualityCmaintenanceMCP server that enables AI agents to search Korean laws and retrieve article contents using the Korean Ministry of Legislation's law information API.2-
- FlicenseNot gradedqualityCmaintenanceMCP server that searches and filters DART electronic disclosures for Korean companies, enabling AI agents to create investor briefing summaries.-
- AlicenseNot gradedqualityCmaintenanceMCP server for Korean government power/energy statutory plans. Enables AI agents to search and retrieve public power plan documents.MIT