๐ [Project] AI ๋ด ์ง์ ๋ง๋ค๊ธฐ: MCP ๋ก์ปฌ ์๋ฒ ๊ตฌ์ถ๊ณผ ์ค๋ฅ์ ์ ์
๐ ๏ธ ์ค์ ํธ๋ฌ๋ธ์ํ
: fastapi-mcp์ ๋ณด๋ธ 48์๊ฐ์ ๊ธฐ๋ก
Django์ ์ต์ํ ์ ์๊ฒ FastAPI๋ ๋งค๋ ฅ์ ์ธ ์ ์ธ๊ณ์์ต๋๋ค. ํ์ง๋ง 'Zero Configuration'์ ํ๋ฐฉํ๋ fastapi-mcp ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋๋ฉด์ ์์์น ๋ชปํ ๋๊ด์ ๋ถ๋ชํ์ต๋๋ค.
1. mount() ๋ฉ์๋์ Deprecation ๊ฒฝ๊ณ
๋๋ถ๋ถ์ ์ฐธ์กฐ ๋ฌธ์์์๋ mcp.mount(app)๋ฅผ ๊ถ์ฅํฉ๋๋ค. ํ์ง๋ง ์ต์ ๋ฒ์ (25๋
ํ๋ฐ๊ธฐ ๊ธฐ์ค)์์๋ ์ด ๋ฉ์๋์ ์ทจ์์ ์ด ๊ทธ์ด์ง๋ฉฐ Deprecated ๊ฒฝ๊ณ ๊ฐ ๋น๋๋ค.
-
ํด๊ฒฐ์ฑ : ์ด์ ๋ ์ ์ก ๋ฐฉ์์ ๋ฐ๋ผ
mount_http()๋๋mount_sse()๋ฅผ ๋ช ์์ ์ผ๋ก ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๊ณต์ ๋ฌธ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์ต์ ํ๋mount_http()๋ฅผ ๊ถ์ฅํฉ๋๋ค.
2. "Client must accept text/event-stream" ์๋ฒ ์๋ฌ์ ๊ณตํฌ
๊ถ์ฅ ๋ฐฉ์์ธ mount_http()๋ฅผ ์ ์ฉํ๊ณ /mcp ๊ฒฝ๋ก๋ฅผ ํ์ธํ์ ๋, ์ ๋ฅผ ๋ฐ๊ธด ๊ฒ์ ํ๋ คํ ๊ด๋ฆฌ์ ํ์ด์ง๊ฐ ์๋ ์๋์ ์ฐจ๊ฐ์ด JSON ์๋ฌ ๋ฉ์์ง์์ต๋๋ค.
{"jsonrpc":"2.0","id":"server-error","error":{"code":-32600,"message":"Not Acceptable: Client must accept text/event-stream"}}
์ด ๋ฉ์์ง ๋๋ฌธ์ ์ ๋ "์๋ฒ ์ธํ
์ด ์๋ชป๋์๋ค"๊ณ ํ๋จํ๊ณ ์ ์๊ฐ์ ํ๋นํ์ต๋๋ค. ํ์ง๋ง ์ฌ๊ธฐ์ ๋ฐ์ ์ด ์ผ์ด๋ฉ๋๋ค. ๋ธ๋ผ์ฐ์ ์์ ๋ณด์ด๋ ์ด ์๋ฌ๋ฅผ ๋ฌด์ํ๊ณ ์ค์ MCP ํด๋ผ์ด์ธํธ(TradeNPU_AI)์์ ๋๊ตฌ๋ฅผ ํธ์ถํ๋ฉด ์ ์ ์๋ํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ text/event-stream์ ์๋ฝํ๋๋ก ์ค์ ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ํ์์ผ ๋ฟ, ์๋ฒ๋ ์ด๋ฏธ ์ค๋น๋ ์ํ์๋ ๊ฒ์ด์ฃ .
3. mount_sse()์ ํจ์ ๊ณผ 405 ์๋ฌ
์๋ฌ ๋ฉ์์ง๋ฅผ ์์ ๋ณด๋ ค๊ณ mount_sse()๋ก ์ฐํํ์ ๋, ๊ฒ์ผ๋ก๋ ํ(Ping)์ด ์ค๊ฐ๋ฉฐ ์ ์์ฒ๋ผ ๋ณด์์ต๋๋ค. ํ์ง๋ง ์ค์ ๋๊ตฌ๋ฅผ ํธ์ถํ์ 405 Method Not Allowed ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ถ๋ช
POST๋ก ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ฒ ๋ก๊ทธ์๋ POST๋ก ์ฐํ๋๋ฐ, ์์ธ ๋ชจ๋ฅผ ๊ฑฐ๋ถ ๋ฐ์์ด ์ผ์ด๋ ๊ฒ์ด์ฃ .
๊ฒฐ๋ก : ๋ฐค์ ์ ์ค์ณ๊ฐ๋ฉฐ ๋ด๋ฆฐ ํด๋ต์ "์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฏฟ์ง ๋ง๊ณ ๊ถ์ฅ ์ธํ
(mount_http)์ผ๋ก ๋ฐ์ด๋ถ์ฌ๋ผ"์์ต๋๋ค. ๊ฒ๋ชจ์ต(๋ธ๋ผ์ฐ์ ๊ฒฐ๊ณผ)์ ์์ง ์๋ ๊ฒ์ด ์ด๋ฒ ํธ๋ฌ๋ธ์ํ
์ ํต์ฌ์ด์์ต๋๋ค.
๐ง ๊นจ๋ฌ์์ ๊ธฐ๋ก: MCP์ Function Calling์ '์ง์ง' ๊ด๊ณ
์ค์ ์ฝ๋๋ฅผ ์ง๋ณด๋ฉฐ ์ด์ ์ ์ ๊ฐ ๊ฐ์ก๋ ์คํด๋ค์ ๋ฐ๋ก์ก๊ฒ ๋์์ต๋๋ค.
1. MCP vs Function Calling? (๋น๊ต ๋์์ด ์๋๋๋ค)
๊ณผ๊ฑฐ์ ์ ๋ ๋ ๊ฐ๋ ์ ๋๋ฑํ ์ ํ์ง๋ก ๋ณด์์ต๋๋ค. ํ์ง๋ง ๋ง๋ค์ด๋ณด๋ ์ด ๋์ ํฌํจ ๊ด๊ณ์ ๊ฐ๊น์ต๋๋ค.
-
Function Calling: AI๊ฐ ํจ์๋ฅผ ํธ์ถํ๋ ํ์์ ๋ฐฉ๋ฒ๋ก ์ ๋๋ค.
-
MCP (Model Context Protocol): ๊ทธ ํธ์ถ ๊ณผ์ ์ ๊ท๊ฒฉํํ๊ณ ํ์คํํ ๊ท์ฝ(Protocol)์ ๋๋ค. ์ฆ, MCP ์๋ฒ ์์์๋ ๊ฒฐ๊ตญ Function Calling์ด ์ผ์ด๋ฉ๋๋ค. "์ด๋ค ๋ฐฉ์์ด ๋ ํ์ง์ด ์ข์๊น?"๋ผ๋ ๊ณ ๋ฏผ์ ๋ฌด์๋ฏธํฉ๋๋ค. ๊ฒฐ๊ตญ ํธ์ถ๋ ํจ์๊ฐ ๋ด๋๋ ๊ฒฐ๊ณผ๊ฐ์ ์ ์ฝ์ด ํ์ง์ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
2. ๋ก์ปฌ vs ์๊ฒฉ? (๊ฒฐ๊ตญ์ '์๊ฒฉ'์ด ๋ต์ด๋ค)
"ํ์ํ ๋๋ง ๋ก์ปฌ ์๋ฒ๋ฅผ ์ผ ๋ค"๋ ์ด๊ธฐ ๋ฐ์์ '24์๊ฐ ์์ฃผํ๋ AI ์ง์'์ด๋ผ๋ ๋ชฉ์ ์ ๋ถํฉํ์ง ์์ต๋๋ค.
-
ํ์ค์ ๋ฌธ์ : ์ ๋ IP ๋ฌธ์ , ๋ฐฉํ๋ฒฝ ๊ฐ๋ฐฉ์ ์ํ์ฑ, 24์๊ฐ ๊ฐ๋์ ๋ถ์์ ์ฑ.
-
๋์๊ฐ ๋ฐฉํฅ: ์ ๋๋ก ๋ ์ ๋ฌด ์์์ ์ํด์๋ MCP ์๋ฒ ์ญ์ ์๊ฒฉ ํ๊ฒฝ์์ ์์ ์ ์ผ๋ก ํธ์คํ ๋์ด์ผ ํฉ๋๋ค. "๋ชจ๋์๊ฒ ์ด๋ก์ด ์๋น์ค๋ฅผ ๋ง๋ค๊ฒ ๋ค"๋ ๊ด์ ์์๋ ์๊ฒฉ ๋ฐฐํฌ๋ ํ์์ ์ ๋๋ค.
โญ ๋ค์ ๋จ๊ณ: ์ค์ง์ ์ธ '๋๊ตฌ'์ ๊ตฌํ
์ด์ ์ํคํ ์ฒ์ ์๋ฒ ์ธํ ์ ๋ํ ์ง๋ฃจํ(?) ์จ๋ฆ์ ๋๋ฌ์ต๋๋ค. ๋ค์ ๊ธ์์๋ ์ค์ ๋ก AI ์ง์์ด ์ ๋ฌด๋ฅผ ์ํํ ์ ์๋๋ก DRF(Django REST Framework)๋ฅผ ํ์ฉํด ๊ตฌ์ฒด์ ์ธ CRUD ์๋ํฌ์ธํธ๋ฅผ ๋ง๋๋ ๊ณผ์ ์ ๊ณต์ ํ๊ฒ ์ต๋๋ค.
๐ก ์๋ด: ์ด ํฌ์คํ ์ ๊ธฐ์กด ๋ค์ด๋ฒ ๋ธ๋ก๊ทธ์ '๊ฐ๋ฐ์ฉ MCP ๋ก์ปฌ์๋ฒ ๋ง๋ค๊ธฐ' ์๋ฆฌ์ฆ๋ฅผ ํตํฉํ ๊ธ์ ๋๋ค. fastapi-mcp ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉฐ ๊ฒช์ ์น๋ช ์ ์ธ ์ค๋ฅ๋ค๊ณผ, ์ด๋ฅผ ํตํด ์ ๋ฆฝํ MCP์ Function Calling์ ์ฌ๋ฐ๋ฅธ ๊ด๊ณ๋ฅผ ๋ค๋ฃน๋๋ค.