Skip to main content
Glama

joo_mcp — FastAPI + Gemini + MCP 학습 예제

MCP를 처음 접하는 사람도 따라 할 수 있도록 만든 교육용 예제입니다. 자연어로 메모(note)를 CRUD 하는 작은 앱을 만들면서 MCP의 핵심을 익힙니다.

사용자: "내일 회의 준비라는 메모 만들어줘"
   │
   ▼  (HTTP POST /chat)
FastAPI 앱  ──►  Gemini API  ──►  MCP 서버(도구: create_note 등)  ──►  SQLite DB
   │                                                                      │
   ◄──────────────  "id=1 로 '내일 회의 준비' 메모를 만들었습니다" ◄──────────┘

1. 먼저 읽어보세요 (MCP 개념)

MCP가 처음이라면 아래 문서를 순서대로 읽으면 됩니다.

순서

문서

내용

1

docs/01-MCP란-무엇인가.md

MCP가 무엇이고 왜 필요한가 (비유로 설명)

2

docs/02-MCP-아키텍처.md

Host / Client / Server 구조와 도구 호출 흐름

3

docs/03-프로젝트-동작-방식.md

이 코드가 실제로 어떻게 동작하는지 줄줄이 설명

4

docs/04-비용과-세션-최적화.md

세션 재사용·컨텍스트 캐싱으로 지연/비용 줄이기

5

docs/05-랭그래프-의도파악.md

LangGraph 로 엔티티 기반 의도 파악 (/intent)

6

docs/06-시나리오-LLM-CRUD.md

LLM 이 메모를 MCP 로 CRUD 하는 시나리오 (흐름→코드 라인→엣지케이스→검증 로그)

💡 위 시나리오를 단계별 애니메이션으로 보려면 dashboard/scenarios.html 을 브라우저로 열면 됩니다. 서버·API 키 없이 동작하는 정적 대시보드입니다.


Related MCP server: Fastidious MCP Server

2. 프로젝트 구조 (표준 레이어드 아키텍처)

요청은 위에서 아래로만 흐릅니다: Router → Service → Repository → DB

joo_mcp/
├── README.md
├── requirements.txt
├── .env.example
│
├── docs/                          ← MCP 교육 자료
│   ├── 01-MCP란-무엇인가.md
│   ├── 02-MCP-아키텍처.md
│   └── 03-프로젝트-동작-방식.md
│
├── mcp_server/
│   └── server.py                  ← ★ MCP 서버: 메모 CRUD 도구 5개 (Repository 재사용)
│
└── app/
    ├── main.py                    ← ★ 앱 팩토리: 라우터/예외/lifespan 조립
    ├── core/
    │   ├── config.py              ←   설정(pydantic-settings)
    │   └── exceptions.py          ←   도메인 예외
    ├── api/
    │   ├── deps.py                ←   의존성 주입(DI) 제공자
    │   └── routes/
    │       ├── notes.py           ←   /notes 라우터 (직접 REST CRUD)
    │       ├── chat.py            ←   /chat 라우터 (AI CRUD, LLM이 도구 선택)
    │       └── intent.py          ←   /intent 라우터 (LangGraph 의도 파악)
    ├── services/
    │   ├── note_service.py        ←   메모 비즈니스 로직
    │   ├── chat_service.py        ← ★ Gemini ↔ MCP 오케스트레이션 (핵심)
    │   ├── intent_graph.py        ← ★ LangGraph 엔티티 기반 의도 파악
    │   └── mcp_session.py         ←   영속 MCP 세션 매니저 (요청당 subprocess 제거)
    ├── repositories/
    │   └── note_repository.py     ← ★ 데이터 접근(SQL). REST와 MCP가 공유
    ├── models/note.py             ←   도메인 모델
    ├── schemas/note.py            ←   요청/응답 DTO
    └── db/database.py             ←   DB 연결/초기화

★ 표시가 핵심 파일입니다. 계층별 책임은 docs/03-프로젝트-동작-방식.md에서 코드와 함께 설명합니다.


3. 설치 및 실행

(1) 가상환경 + 패키지 설치

# Windows PowerShell 기준
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
# macOS / Linux
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

(2) API 키 설정

Google AI Studio에서 Gemini API 키를 발급받은 뒤:

copy .env.example .env      # macOS/Linux: cp .env.example .env

.env 파일을 열어 GEMINI_API_KEY 값을 채웁니다.

(3) 서버 실행

uvicorn app.main:app --reload

MCP 서버(mcp_server/server.py)는 따로 실행하지 않습니다. FastAPI 앱이 시작 시 한 번 하위 프로세스로 띄워 앱 수명 동안 재사용합니다. (요청마다 띄우지 않아 지연이 줄어듭니다 — docs/04)

실행 후 브라우저에서 http://127.0.0.1:8000/docs 를 열면 Swagger UI로 모든 API를 직접 눌러볼 수 있습니다.


4. 사용해보기

A. 직접 REST CRUD (MCP/AI 없이)

# Create
curl -X POST http://127.0.0.1:8000/notes -H "Content-Type: application/json" -d "{\"title\":\"장보기\",\"content\":\"우유, 계란\"}"

# Read (전체)
curl http://127.0.0.1:8000/notes

# Update
curl -X PUT http://127.0.0.1:8000/notes/1 -H "Content-Type: application/json" -d "{\"content\":\"우유, 계란, 빵\"}"

# Delete
curl -X DELETE http://127.0.0.1:8000/notes/1

B. AI 기반 CRUD (FastAPI → Gemini → MCP)

curl -X POST http://127.0.0.1:8000/chat -H "Content-Type: application/json" -d "{\"message\":\"내일 회의 준비라는 제목으로 메모 만들어줘\"}"

curl -X POST http://127.0.0.1:8000/chat -H "Content-Type: application/json" -d "{\"message\":\"메모 목록 보여줘\"}"

curl -X POST http://127.0.0.1:8000/chat -H "Content-Type: application/json" -d "{\"message\":\"1번 메모 삭제해줘\"}"

/chat으로 만든 메모는 GET /notes로도 똑같이 보입니다. 같은 DB를 사람과 AI가 공유하기 때문입니다. — 이것이 MCP의 핵심 가치입니다.

C. LangGraph 의도 파악 (엔티티 → 의도 → 실행)

/chat은 Gemini가 도구를 직접 고르지만, /intent엔티티를 추출해 의도를 명시적으로 파악한 뒤 실행합니다. 응답에 인식한 엔티티/의도가 그대로 담깁니다.

curl -X POST http://127.0.0.1:8000/intent -H "Content-Type: application/json" -d "{\"message\":\"회의록 이라는 제목으로 메모 만들어줘\"}"
# → {"intent":"create","entities":{"action":"create","title":"회의록",...},"reply":"메모를 생성했습니다. (id=1)"}

자세한 그래프 구조는 docs/05 참고.


5. 테스트 (e2e)

CRUD 전체를 두 경로로 검증하는 e2e 테스트가 tests/ 에 있습니다. 각 테스트는 임시 SQLite 파일로 격리되어 실제 notes.db 를 건드리지 않습니다.

pip install -r requirements.txt -r requirements-dev.txt
pytest

파일

검증 대상

tests/test_notes_api_e2e.py

직접 REST CRUD (생성/조회/수정/삭제 + 404·422)

tests/test_mcp_server_e2e.py

MCP 서버 도구 CRUD (실제 서버를 stdio 로 띄워 호출)

tests/test_intent.py

LangGraph 의도 분류/응답(결정론적) + 그래프 e2e(SKIP)

tests/test_chat_e2e.py

AI 경로(FastAPI→Gemini→MCP). 기본 SKIP

test_chat_e2e.py 는 실제 Gemini 를 호출하므로 비용/비결정성 때문에 기본으로 건너뜁니다. 돌리려면 GEMINI_API_KEY 설정 후:

$env:RUN_CHAT_E2E="1"; pytest tests/test_chat_e2e.py -v

6. 무엇을 배우게 되나요?

  • MCP 서버 만들기: @mcp.tool() 로 함수를 AI가 쓸 수 있는 도구로 노출

  • MCP 클라이언트 연결: stdio 로 서버 프로세스를 띄우고 세션 연결

  • Gemini 도구 연동: MCP 도구를 Gemini FunctionDeclaration 으로 변환하고 함수 호출 루프로 실행

  • CRUD 설계: 같은 데이터 저장소를 REST API 와 AI 도구가 함께 사용

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Enables to manage notes and collections in Fastidious AI application through natural language, supporting CRUD operations and search via MCP protocol.
    11
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables CRUD operations on notes stored in PostgreSQL, with tools to list, create, update, delete notes and tags. The server provides both REST API and MCP endpoints via a single FastAPI process.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server for a full-stack note-taking application, exposing CRUD tools for notes with SSE transport for AI agent integration.
    1
    -