Youth Policy Navigator
<div align="center">
# ๐งญ Youth Policy Navigator
### ์ฒญ๋
์ ์ฑ
๊ฒ์ยท์๊ฒฉ ํ์ ์ ์ํ MCP Server
**Search โ Eligibility Check โ Missing Info โ Memory โ Re-evaluation**





**Kakao PlayMCP ๊ณต๋ชจ์ ํ๋ก์ ํธ**
</div>
์ฒญ๋
์ ์ฑ
ยท์ง์๊ธ์ ๋จ์ ๊ฒ์ํ๋ ๋ฐ์ ๋๋์ง ์๊ณ , **์ฌ์ฉ์์ ์ํฉ๊ณผ ์ ์ฑ
์กฐ๊ฑด์ ๋น๊ตํด ์ ๊ฒฉ / ๋ถ์ ๊ฒฉ / ์ ๋ณด๋ถ์กฑ์ ์ด์ ์ ํจ๊ป ํ์ **ํ๋ MCP ์๋ฒ์
๋๋ค.
## Why this project?
| Feature | What it does |
|---|---|
| ๐ **Hybrid Search** | ์จํต์ฒญ๋
API + ๋ด์ฅ corpus๋ฅผ Contextual BM25๋ก ๊ฒ์ |
| โ
**Deterministic Eligibility** | ๋์ดยท์ง์ญยท์๋ยท์ทจ์
์ํ๋ฅผ ๊ตฌ์กฐํ ์กฐ๊ฑด์ผ๋ก ํ์ |
| โ **Missing-info Loop** | ์ ๋ณด๊ฐ ๋ถ์กฑํ๋ฉด ๋ค์ ์ง๋ฌธ์ ๋ง๋ค์ด host LLM์ด ๋๋ฌป๊ฒ ํจ |
| ๐ง **User Memory** | SQLite์ ์ฌ์ฉ์ ์ํฉ์ ์ ์ฅํ๊ณ ํ์ํ ์ ๋ณด๋ฅผ ํ์ |
| ๐งฉ **MCP Tools** | ์์ฐ์ด ์์ฑ์ host LLM, ๋ฐ์ดํฐยทํ์ ์ server๊ฐ ๋ด๋น |
## Agent Loop
```mermaid
flowchart LR
U[User Query] --> S[Policy Search]
S --> E[Eligibility Check]
E -->|Enough info| R[Reasoned Result]
E -->|Missing info| Q[Follow-up Question]
Q --> M[Remember Profile]
M --> E
```
์๋ฒ๊ฐ โ๋ต๋ณ ๋ฌธ์ฅโ์ ๋ง์๋๋ก ์์ฑํ์ง ์๊ณ , **๊ทผ๊ฑฐ ๋ฐ์ดํฐ์ ๊ฒฐ์ ๋ก ์ ํ์ ๊ฒฐ๊ณผ**๋ฅผ ์ ๊ณตํ๋๋ก ์ญํ ์ ๋ถ๋ฆฌํ ๊ฒ์ด ํต์ฌ์
๋๋ค.
## MCP Tools
| Tool | Role |
|---|---|
| `search_youth_policies` | ์ ์ฑ
๊ฒ์ |
| `check_eligibility` | ์ฌ์ฉ์ ์กฐ๊ฑด ๊ธฐ๋ฐ ์๊ฒฉ ํ์ |
| `get_policy_detail` | ์ ์ฒญ ๋ฐฉ๋ฒยท๊ธฐ๊ฐยท์๋ฅยทURL |
| `remember_user_profile` | ์ฌ์ฉ์ ์ํฉ ์ ์ฅ |
| `recall_user_profile` | ๊ด๋ จ ์ฌ์ฉ์ ์ ๋ณด ํ์ |
## Example
1. โ์์ธ ์ง์ ์ ์ฑ
์ฐพ์์คโ โ ๊ด๋ จ ์ ์ฑ
๊ฒ์
2. ์๊ฒฉ ํ์ ์ ์๋ ์ ๋ณด๊ฐ ๋ถ์กฑํจ โ `needs_more_info`
3. host LLM์ด ์๋ ์ ๋ณด๋ฅผ ์ง๋ฌธ
4. ๋ต๋ณ์ memory์ ์ ์ฅ
5. ๋์ผ ์ ์ฑ
์ ๋ค์ ํ์ โ `eligible / ineligible / manual_review`
## Quick Start
```bash
uv sync --extra dev
uv run pytest -q
# local stdio
uv run policy-mcp
# remote HTTP
MCP_TRANSPORT=http uv run policy-mcp
```
Docker:
```bash
docker build --platform linux/amd64 -t policy-mcp .
```
API key๊ฐ ์์ด๋ ๋ด์ฅ corpus ๊ธฐ๋ฐ mock์ผ๋ก ๋์ํฉ๋๋ค.
<details>
<summary><b>Live ์จํต์ฒญ๋
API ์ฌ์ฉํ๊ธฐ</b></summary>
`.env`์ ๋ฐ๊ธ๋ฐ์ ์ ์ฑ
API ํค๋ฅผ ์ค์ ํฉ๋๋ค.
```env
YOUTHCENTER_API_KEY_POLICY=your_api_key
```
2026-07 ๊ธฐ์ค ์ ๊ท API ๊ท๊ฒฉ์ ์ค์ ๋ฐ๊ธํค๋ก ๊ฒ์ฆํ์ต๋๋ค. ์ ์ฑ
์กฐ๊ฑด์ ๊ณต๊ณ ์ ๋ฐ๋ผ ๋ณ๋๋ ์ ์์ผ๋ฏ๋ก ์ต์ข
์ ์ฒญ ์ ์๋ฌธ ๊ณต๊ณ ํ์ธ์ด ํ์ํฉ๋๋ค.
</details>
## Project Structure
```text
src/policy_mcp/
โโโ server.py # FastMCP server / tools
โโโ policies.py # search service
โโโ eligibility.py # deterministic eligibility engine
โโโ policy_corpus.py # built-in policy corpus
โโโ memory.py # SQLite + BM25 memory
โโโ retrieval.py # Contextual BM25
โโโ clients/ # Youth Center API client
tests/ # 48 offline tests
```
## Design Principle
> **LLM์ ํด์๊ณผ ๋ํ๋ฅผ ๋ด๋นํ๊ณ , eligibility decision์ ์ฌํ ๊ฐ๋ฅํ ์ฝ๋๊ฐ ๋ด๋นํ๋ค.**
์ด ๊ตฌ์กฐ๋ฅผ ํตํด ์ ์ฑ
๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋๋๋ผ๋ ์๊ฒฉ ํ์ ๊ณผ์ ๊ณผ ๊ทผ๊ฑฐ๋ฅผ ์ถ์ ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์์ต๋๋ค.
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: searching policies, checking eligibility, retrieving details, managing user profiles, and finding centers. No overlapping functions; agents can easily differentiate.
All tools follow a consistent verb_noun pattern in snake_case (e.g., check_eligibility, search_youth_policies, remember_user_profile). No mixing of conventions.
With 6 tools, the server captures the essential workflow for youth policy navigation: search, detailed view, eligibility check, user context management, and offline center lookup. Well-scoped without bloat.
Core operations are covered: search, detail, eligibility, profile persistence, and location guidance. A minor gap is the absence of a tool to list all policies or update user profiles, but the current set handles typical user journeys effectively.