minchae-me/mcp
3.1
If you are the rightful owner of mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
This project demonstrates the automatic generation of an MCP server from an OpenAPI specification using FastMCP.
FastMCP OpenAPI μλ μμ± λ°λͺ¨
μ΄ νλ‘μ νΈλ FastMCPλ₯Ό μ¬μ©νμ¬ OpenAPI μ€νμμ μλμΌλ‘ MCP(Model Context Protocol) μλ²λ₯Ό μμ±νκ³ Swagger UIλ₯Ό μ 곡νλ λ°λͺ¨μ λλ€.
π μ£Όμ κΈ°λ₯
- OpenAPI μ€ν μλ λ³ν: OpenAPI 3.0 μ€νμ MCP μλ²λ‘ μλ λ³ν
- FastAPI ν΅ν©: FastAPI μ±μ MCP μλ²λ‘ μλ λ³ν
- Swagger UI μ 곡: μΉ λΈλΌμ°μ μμ API λ¬Έμ νμΈ κ°λ₯
- μλ ν μ€νΈ: μμ±λ MCP μλ²μ κΈ°λ₯μ μλμΌλ‘ ν μ€νΈ
- νλμ μΈ λꡬ: uv, pyproject.toml μ¬μ©
π λΉ λ₯Έ μμ
1. uv μ€μΉ (κΆμ₯)
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# λλ pipλ‘ μ€μΉ
pip install uv
2. νλ‘μ νΈ μ€μ
# νλ‘μ νΈ ν΄λ‘ λ° λλ ν 리 μ΄λ
git clone <repository-url>
cd fastmcp-openapi-demo
# uvλ‘ κ°μνκ²½ μμ± λ° μμ‘΄μ± μ€μΉ
uv sync
# λλ κ°λ° μμ‘΄μ±κΉμ§ ν¬ν¨ν΄μ μ€μΉ
uv sync --dev
3. λ°λͺ¨ μ€ν
# λ°©λ² 1: uv runμΌλ‘ μ§μ μ€ν
uv run python run_demo.py
# λ°©λ² 2: μ€ν¬λ¦½νΈ λͺ
λ Ήμ΄ μ¬μ©
uv run fastmcp-demo
# λ°©λ² 3: κ°μνκ²½ νμ±ν ν μ€ν
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
python run_demo.py
π οΈ κ°λ° νκ²½ μ€μ
μ½λ νμ§ λꡬ
# μ½λ ν¬λ§·ν
uv run black .
# λ¦°ν
uv run ruff check .
uv run ruff check . --fix # μλ μμ
# νμ
체νΉ
uv run mypy .
# ν
μ€νΈ μ€ν
uv run pytest
μλ‘μ΄ μμ‘΄μ± μΆκ°
# λ°νμ μμ‘΄μ± μΆκ°
uv add package-name
# κ°λ° μμ‘΄μ± μΆκ°
uv add --dev package-name
# νΉμ λ²μ μ§μ
uv add "fastapi>=0.104.0"
π ν΄κ²°λ λ¬Έμ λ€
β κΈ°μ‘΄ λ¬Έμ μ λ€
- ν
μ€νΈ μ€λ₯:
'list' object has no attribute 'tools'
- asyncio μΆ©λ:
Already running asyncio in this thread
- MCP μλν¬μΈνΈ 404:
/mcp
κ²½λ‘ μ κ·Ό λΆκ° - ν¨ν€μ§ κ΄λ¦¬: λλ¦° pip, 볡μ‘ν κ°μνκ²½ κ΄λ¦¬
β ν΄κ²° λ°©μ
- API νΈνμ± κ°μ : tools/resources κ°μ²΄ νμ κ²μ¬ μΆκ°
- λ
립 μλ² μμ±:
standalone_mcp_server.py
λ‘ asyncio μΆ©λ ν΄κ²° - FastAPI ν΅ν© κ°μ : MCP μ 보 μλν¬μΈνΈ μΆκ°
- νλμ μΈ λꡬ: uv μ¬μ©μΌλ‘ λΉ λ₯Έ μμ‘΄μ± κ΄λ¦¬
π μΉ μΈν°νμ΄μ€
FastAPI μλ² μ€ν ν λΈλΌμ°μ μμ λ€μ URL μ μ:
- λ©μΈ νμ΄μ§: http://localhost:8000
- FastAPI Swagger UI: http://localhost:8000/docs β κΆμ₯
- 컀μ€ν Swagger UI: http://localhost:8000/swagger
- MCP μ 보: http://localhost:8000/mcp/info
- OpenAPI μ€ν: http://localhost:8000/openapi.json
π νμΌ κ΅¬μ‘°
.
βββ pyproject.toml # νλ‘μ νΈ μ€μ λ° μμ‘΄μ±
βββ .python-version # Python λ²μ μ§μ
βββ uv.lock # μμ‘΄μ± μ κΈ νμΌ (μλ μμ±)
βββ openapi_mcp_server.py # λ©μΈ MCP μλ² κ΅¬ν
βββ standalone_mcp_server.py # λ
립 STDIO MCP μλ²
βββ test_mcp_client.py # MCP ν΄λΌμ΄μΈνΈ ν
μ€νΈ
βββ run_demo.py # λ°λͺ¨ μ€ν μ€ν¬λ¦½νΈ
βββ README.md # μ΄ λ¬Έμ
π§ ꡬν λ°©λ²
1. OpenAPI μ€νμμ MCP μλ² μμ±
from fastmcp import FastMCP
from fastmcp.server.openapi import RouteMap, MCPType
import httpx
# HTTP ν΄λΌμ΄μΈνΈ μμ±
client = httpx.AsyncClient(base_url="https://api.example.com")
# OpenAPI μ€ν λ‘λ
openapi_spec = {...} # OpenAPI 3.0 μ€ν
# MCP μλ² μμ±
mcp = FastMCP.from_openapi(
openapi_spec=openapi_spec,
client=client,
name="My API Server"
)
# μλ² μ€ν
await mcp.run()
2. FastAPI μ±μμ MCP μλ² μμ±
from fastapi import FastAPI
from fastmcp import FastMCP
# FastAPI μ± μμ±
app = FastAPI()
@app.get("/items")
def get_items():
return [{"id": 1, "name": "Item 1"}]
# FastAPIλ₯Ό MCP μλ²λ‘ λ³ν
mcp = FastMCP.from_fastapi(app=app)
# μλ² μ€ν
await mcp.run()
π§ͺ ν μ€νΈ
# λͺ¨λ ν
μ€νΈ μ€ν
uv run pytest
# νΉμ ν
μ€νΈ νμΌ μ€ν
uv run pytest test_mcp_client.py
# 컀λ²λ¦¬μ§ ν¬ν¨ ν
μ€νΈ
uv run pytest --cov=. --cov-report=html
π uv vs pip λΉκ΅
κΈ°λ₯ | uv | pip |
---|---|---|
μλ | π 10-100λ°° λΉ λ¦ | π λλ¦Ό |
μμ‘΄μ± ν΄κ²° | β κ³ κΈ μκ³ λ¦¬μ¦ | β οΈ κΈ°λ³Έμ |
κ°μνκ²½ | β ν΅ν© κ΄λ¦¬ | β λ³λ λꡬ νμ |
μ κΈ νμΌ | β uv.lock | β μμ |
ν¬λ‘μ€ νλ«νΌ | β μΌκ΄λ κ²½ν | β οΈ νλ«νΌλ³ μ°¨μ΄ |
π‘ uv μ¬μ© ν
# νλ‘μ νΈ μ΄κΈ°ν
uv init my-project
cd my-project
# Python λ²μ μ€μ
uv python pin 3.12
# μμ‘΄μ± μ€μΉ (pyproject.toml κΈ°λ°)
uv sync
# μ€ν¬λ¦½νΈ μ€ν
uv run python script.py
# ν¨ν€μ§ μΆκ°/μ κ±°
uv add requests
uv remove requests
# κ°λ° μλ² μ€ν
uv run uvicorn app:app --reload
π€ κΈ°μ¬νκΈ°
- μ μ₯μλ₯Ό ν¬ν¬ν©λλ€
- κΈ°λ₯ λΈλμΉλ₯Ό λ§λλλ€:
git checkout -b feature/amazing-feature
- uvλ₯Ό μ¬μ©ν΄ κ°λ° νκ²½μ μ€μ ν©λλ€:
uv sync --dev
- μ½λ νμ§ λꡬλ₯Ό μ€νν©λλ€:
uv run black . && uv run ruff check .
- ν
μ€νΈλ₯Ό μ€νν©λλ€:
uv run pytest
- λ³κ²½μ¬νμ 컀λ°ν©λλ€:
git commit -m 'Add amazing feature'
- λΈλμΉμ νΈμν©λλ€:
git push origin feature/amazing-feature
- Pull Requestλ₯Ό μ½λλ€
π λΌμ΄μΌμ€
μ΄ νλ‘μ νΈλ MIT λΌμ΄μΌμ€ νμ λ°°ν¬λ©λλ€.
π μ§μ
λ¬Έμ κ° μκ±°λ μ§λ¬Έμ΄ μμΌμλ©΄ μ΄μλ₯Ό μμ±ν΄ μ£ΌμΈμ.