Skip to main content
Glama
todayoneul

Youth Policy Navigator

by todayoneul
README.md
<div align="center">

# ๐Ÿงญ Youth Policy Navigator

### ์ฒญ๋…„ ์ •์ฑ… ๊ฒ€์ƒ‰ยท์ž๊ฒฉ ํŒ์ •์„ ์œ„ํ•œ MCP Server

**Search โ†’ Eligibility Check โ†’ Missing Info โ†’ Memory โ†’ Re-evaluation**

![Python](https://img.shields.io/badge/Python-3776AB?style=flat-square&logo=python&logoColor=white)
![MCP](https://img.shields.io/badge/MCP-FastMCP-black?style=flat-square)
![SQLite](https://img.shields.io/badge/SQLite-003B57?style=flat-square&logo=sqlite&logoColor=white)
![Docker](https://img.shields.io/badge/Docker-2496ED?style=flat-square&logo=docker&logoColor=white)
![Tests](https://img.shields.io/badge/Tests-48%20offline-success?style=flat-square)

**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

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivitySlowing
ResponsivenessNo issues