Skip to main content
Glama
kimgyver

Python MCP All-in-One

by kimgyver
README.md
# Python MCP All-in-One

FastMCP로 만든 **학습용 MCP 예제**입니다.  
Cursor 같은 MCP 클라이언트에서 **Tool**(실행)과 **Resource**(읽기 전용 컨텍스트)를 나눠 체험할 수 있습니다.

| 구분 | 역할 | 엔트리포인트 |
|------|------|----------------|
| **Tools** | OS 조회, 파일 R/W, 날씨, SQLite | `src/server.py` |
| **Resources** | 가이드 문서, 유저 프로필 | `src/server_resources.py` |

## 구조

```
python-mcp-all-in-one/
├── src/
│   ├── server.py              # Tool MCP 서버
│   └── server_resources.py    # Resource MCP 서버
├── docs/
│   └── mcp-guide.md           # Resource로 노출되는 가이드
├── data/
│   └── mcp_sample.db          # SQLite (users 테이블)
├── requirements.txt
└── README.md
```

## 사전 요구

- Python 3.12+
- Cursor (또는 다른 MCP 클라이언트)

## 설치

```bash
cd python-mcp-all-in-one
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

## Cursor MCP 설정

`~/.cursor/mcp.json` 예시 (경로는 본인 환경에 맞게 수정):

```json
{
  "mcpServers": {
    "python-all-in-one-mcp-v2": {
      "command": "/ABS/PATH/python-mcp-all-in-one/.venv/bin/python",
      "args": [
        "/ABS/PATH/python-mcp-all-in-one/src/server.py"
      ]
    },
    "python-mcp-resources": {
      "command": "/ABS/PATH/python-mcp-all-in-one/.venv/bin/python",
      "args": [
        "/ABS/PATH/python-mcp-all-in-one/src/server_resources.py"
      ]
    }
  }
}
```

설정 후 Cursor Settings → MCP에서 두 서버가 **Connected**인지 확인하세요.

> **코드 수정 후 도구/리소스가 안 바뀌면:** MCP Reload만으로는 옛 스냅샷이 남을 수 있습니다.  
> 서버 이름 변경, Cursor 완전 재시작, 또는  
> `rm -rf ~/.cursor/projects/*/mcps` 후 재시작을 시도하세요.

---

## 1) Tools 서버 (`server.py`)

서버 표시 이름: **Python All-in-One MCP**

| Tool | 설명 | 예시 인자 |
|------|------|-----------|
| `get_os_info` | OS / 아키텍처 정보 | (없음) |
| `read_local_file` | 텍스트 파일 읽기 | `file_path` |
| `write_local_file` | 텍스트 파일 쓰기 | `file_path`, `content` |
| `get_current_weather` | 도시 날씨 (wttr.in) | `city` (`seoul`, `auckland` 등) |
| `run_sqlite_query` | SQLite 쿼리 실행 | `query` |

DB 경로: `data/mcp_sample.db`  
`users(id, name, role)` 테이블이 없으면 자동 생성합니다.

### 채팅 테스트 예시

- 내 컴퓨터 OS 정보를 알려줘. (`get_os_info` 사용)
- Auckland 날씨가 어때? (`get_current_weather`)
- `users` 테이블에서 name이 jason인 행을 SQL로 조회해줘. (`run_sqlite_query`)

---

## 2) Resources 서버 (`server_resources.py`)

서버 표시 이름: **Python MCP Resources**

| URI | 종류 | 내용 |
|-----|------|------|
| `resource://docs/mcp-guide` | 정적 | `docs/mcp-guide.md` |
| `resource://users/{user_id}` | 동적 | SQLite `users`에서 `name = user_id` JSON |

샘플 유저 (DB가 비어 있으면 자동 시드):

| user_id | role |
|---------|------|
| `jason` | MCP Explorer |
| `admin` | System Manager |

### Tool vs Resource

| | Tool | Resource |
|--|------|----------|
| 목적 | 행동 / 계산 / 부작용 가능 | 읽기 전용 컨텍스트 |
| 예 | SQL 실행, 파일 쓰기, API 호출 | 문서, 프로필 JSON |

### 채팅 테스트 예시

- `resource://docs/mcp-guide` 내용을 읽어줘.
- `resource://users/jason` 프로필을 보여줘.
- python-mcp-resources에서 가이드랑 jason 프로필을 읽어줘.

---

## 로컬 스모크 테스트 (선택)

```bash
source .venv/bin/activate

# Tools
python -c "
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    params = StdioServerParameters(
        command='.venv/bin/python',
        args=['src/server.py'],
    )
    async with stdio_client(params) as (r, w):
        async with ClientSession(r, w) as s:
            await s.initialize()
            tools = await s.list_tools()
            print([t.name for t in tools.tools])

asyncio.run(main())
"
```

---

## 참고

- MCP Python SDK: [modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk)
- 리소스 상세 설명: [`docs/mcp-guide.md`](docs/mcp-guide.md)