
AI 코드 에디터 Cursor는 개발 과정에서 매우 강력한 도구이지만, colima start
나 docker ps
와 같은 로컬 환경의 명령어를 실행하려면 별도의 터미널 창을 열어야 하는 번거로움이 있다. Cursor의 MCP(Model Context Protocol) 기능을 활용하면 이러한 작업을 에디터 내에서 직접 처리할 수 있다. 하지만 단순 셸 스크립트는 MCP의 통신 방식인 JSON-RPC 2.0 프로토콜을 따르지 않아 직접 연동이 어렵다.
본 문서는 이러한 문제를 해결하기 위해, MCP 명세에 맞는 Python 서버를 구현하고 Cursor에 설정하여 Colima 관련 명령어를 원활하게 실행하는 상세한 절차를 제공하는 것을 목표로 한다.
0. 시작 전 준비 사항
본 튜토리얼을 진행하기에 앞서, 아래의 개발 환경이 구축되어 있는지 확인해야 한다.
- Cursor: AI 코드 에디터 설치 완료
- Colima & Docker: 설치 및 기본 설정 완료
- Python: v3.6 이상 (
python3 --version
명령어로 버전 확인) - 코드 에디터: VS Code 또는 기타 선호하는 편집기
모든 요구사항이 충족되었다면, MCP 서버 스크립트를 저장할 프로젝트 디렉터리를 생성하고 해당 경로로 이동한다.
mkdir mcp-server
cd mcp-server
1단계: MCP 서버 스크립트 작성
가장 먼저, Cursor와 통신할 MCP 서버 역할을 수행할 Python 스크립트를 작성한다. 이 스크립트는 표준 입출력(stdin/stdout)을 통해 JSON-RPC 형식의 메시지를 주고받는다.
생성된 mcp_colima_server.py
파일에 아래의 코드를 작성한다. 이 코드는 `initialize`, `tools/list`, `tools/call`이라는 세 가지 핵심 MCP 메서드를 처리한다.
#!/usr/bin/env python3
import json
import sys
import subprocess
from typing import Dict, Any
class MCPColimaServer:
def __init__(self):
# 보안을 위해 실행 가능한 명령어 목록을 명시적으로 제한한다.
self.allowed_commands = [
"colima", "docker", "docker-compose", "brew",
"ls", "cat", "pwd", "ps", "which", "echo"
]
def handle_request(self, request: Dict[str, Any]) -> Dict[str, Any]:
method = request.get("method")
# 1. 서버 초기화 요청 처리
if method == "initialize":
return {
"jsonrpc": "2.0", "id": request.get("id"), "result": {
"protocolVersion": "2024-11-05", "capabilities": {"tools": {}},
"serverInfo": {"name": "colima-helper", "version": "1.0.0"}
}
}
# 2. 사용 가능한 도구 목록 요청 처리
elif method == "tools/list":
return {
"jsonrpc": "2.0", "id": request.get("id"), "result": {
"tools": [{
"name": "run_command",
"description": "Run allowed shell commands",
"inputSchema": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "Command to execute"}
},
"required": ["command"]
}
}]
}
}
# 3. 실제 명령어 실행 요청 처리
elif method == "tools/call":
params = request.get("params", {})
if params.get("name") == "run_command":
command = params.get("arguments", {}).get("command", "")
result = self.execute_command(command)
return {
"jsonrpc": "2.0", "id": request.get("id"), "result": {
"content": [{"type": "text", "text": result}]
}
}
# 지원하지 않는 메서드에 대한 오류 응답
return {
"jsonrpc": "2.0", "id": request.get("id"),
"error": {"code": -32601, "message": f"Method not found: {method}"}
}
def execute_command(self, command: str) -> str:
# 명령어 첫 부분이 허용 목록에 있는지 검증
cmd_parts = command.split()
if not cmd_parts or cmd_parts[0] not in self.allowed_commands:
return f"Error: Command not allowed: {cmd_parts[0]}"
try:
result = subprocess.run(
command, shell=True, capture_output=True, text=True, timeout=30
)
if result.returncode == 0:
return result.stdout or "Command executed successfully."
else:
return f"Error: {result.stderr}"
except Exception as e:
return f"Error: {str(e)}"
def run(self):
# 표준 입력으로 들어오는 각 라인을 읽어 처리
for line in sys.stdin:
try:
request = json.loads(line.strip())
response = self.handle_request(request)
# 처리 결과를 JSON 형태로 표준 출력
print(json.dumps(response), flush=True)
except (json.JSONDecodeError, Exception) as e:
# 오류 발생 시 JSON-RPC 오류 메시지 출력
error_response = {
"jsonrpc": "2.0", "id": None,
"error": {"code": -32603, "message": f"Internal error: {str(e)}"}
}
print(json.dumps(error_response), flush=True)
if __name__ == "__main__":
server = MCPColimaServer()
server.run()
Python 프로젝트는 의존성 관리를 위해 가상 환경(virtual environment) 내에서 관리하는 것이 모범 사례이다. 아래 명령어를 통해 가상 환경을 생성하고 활성화할 수 있다.
python3 -m venv .venv
source .venv/bin/activate
2단계: 스크립트 실행 권한 부여 및 테스트
작성된 Python 스크립트를 Cursor가 호출할 수 있도록 실행 권한을 부여해야 한다.
chmod +x mcp_colima_server.py
Cursor에 설정하기 전, 스크립트가 MCP 프로토콜에 맞게 올바르게 응답하는지 터미널에서 직접 테스트한다. 아래는 colima status
명령을 테스트하는 예시이다.
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "run_command", "arguments": {"command": "colima status"}}}' | ./mcp_colima_server.py
테스트 실행 시, 아래와 같이 colima status
의 결과가 포함된 JSON 응답이 출력되어야 한다.
{"jsonrpc": "2.0", "id": 1, "result": {"content": [{"type": "text", "text": "INFO[0000] colima is running \nINFO[0000] runtime: docker \nINFO[0000] arch: aarch64 \nINFO[0000] socket: unix:///Users/username/.colima/default/docker.sock \n"}]}}
만약 `command not found` 오류가 발생하면, 스크립트의 경로를 정확히 지정해야 한다. (예:
/path/to/mcp-server/mcp_colima_server.py
) 또한, 스크립트 최상단의 #!/usr/bin/env python3
부분이 올바른 Python 인터프리터를 가리키는지 확인한다.3단계: Cursor MCP 설정 및 결과 확인
스크립트가 정상적으로 작동하는 것을 확인했다면, Cursor의 MCP 설정 파일에 해당 스크립트를 등록한다. Cursor에서 Cmd+Shift+P
를 눌러 "Configure MCP..."를 검색하고 mcp.json
파일을 연다.
열린 mcp.json
파일에 아래와 같이 `colima-helper` 서버 설정을 추가한다. 주의: `command`와 `args`의 경로는 사용자의 실제 프로젝트 경로로 수정해야 한다.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/YOUR_USERNAME/Desktop",
"/Users/YOUR_USERNAME/Documents"
]
},
"colima-helper": {
// 가상 환경을 사용한다면 .venv 안의 python 경로를 지정한다.
"command": "/Users/YOUR_USERNAME/path/to/mcp-server/.venv/bin/python",
"args": [
// 실제 스크립트 파일의 절대 경로를 지정한다.
"/Users/YOUR_USERNAME/path/to/mcp-server/mcp_colima_server.py"
]
}
}
}
설정 파일을 저장한 후, Cursor를 완전히 재시작한다. 재시작 후 채팅 창에서 @
를 입력했을 때 colima-helper
가 보이고, MCP 설정 상태에 "1 tools enabled"라고 표시되면 성공적으로 연동된 것이다.
이제 Cursor 채팅을 통해 다음과 같이 자연어로 명령을 내릴 수 있다.
colima status
명령어 실행 결과입니다.
INFO[0000] colima is running
INFO[0000] runtime: docker
INFO[0000] arch: aarch64
INFO[0000] socket: unix:///Users/dongwoo0518.kim/.colima/default/docker.sock
결론
이상으로 Python 스크립트를 이용해 MCP 서버를 구축하고, 이를 Cursor와 연동하여 Colima 및 Docker 관련 명령어를 실행하는 전 과정을 검토하였다. 이 방법을 통해 터미널과 에디터를 오가는 불편함을 줄이고, AI와의 상호작용만으로 개발 환경을 제어하는 효율적인 워크플로우를 구축할 수 있다.
본 튜토리얼에서 다룬 내용을 바탕으로, `allowed_commands` 목록에 자주 사용하는 다른 명령어들을 추가하여 자신만의 개발 자동화 도구를 만들어보는 것을 권장한다.
'기술' 카테고리의 다른 글
N8N 워크플로우의 핵심: Notion API 연결 및 설정 방법 (1) | 2025.06.18 |
---|---|
.gitlab-ci.yml 하나로 main, dev 브랜치 최신 상태로 동기화하기 (0) | 2025.06.16 |
Spring Batch 무중단 배포: 심볼릭 링크로 ClassNotFoundException 해결 (0) | 2025.06.16 |
n8n을 Cursor AI의 MCP 서버로 활용하기 (0) | 2025.06.16 |
내 서버에 n8n 자동화 허브 구축하기 (feat. Coolify) (0) | 2025.06.15 |