MCP 클라이언트 연동
GenD MCP 서버를 Claude Desktop, Cursor, VS Code Copilot에 연결하여 대화형 AI에서 GenD 데이터를 직접 조회하고 분석하는 방법을 안내합니다.
사전 준비
- GenD 클러스터가 실행 중이어야 합니다
- MCP 서버 엔드포인트에 네트워크 접근이 가능해야 합니다
- 관리자가 MCP 게이트웨이를 활성화한 상태여야 합니다
- 인증 토큰 — 두 옵션 중 하나:
- M2M 서비스 계정 (권장) — 외부 머신/공용 워크스페이스 설정용. admin 이 /admin/service-clients 에서 발급한
client_id+client_secret - 사용자 JWT — 단발성 디버깅용. 브라우저 로그인 후 DevTools 에서 추출
- M2M 서비스 계정 (권장) — 외부 머신/공용 워크스페이스 설정용. admin 이 /admin/service-clients 에서 발급한
MCP 서버 개요
GenD MCP 서버는 JSON-RPC 2.0 Streamable HTTP 프로토콜을 사용합니다.
| 항목 | 값 |
|---|---|
| 엔드포인트 | POST /mcp |
| 프로토콜 | JSON-RPC 2.0 (Streamable HTTP) |
| 도구 | 32개 (카탈로그 탐색, SQL 실행, 거버넌스 등) — 정의 35개 중 쓰기 3개는 GEND_MCP_WRITE_TOOLS_ENABLED 로 게이트 |
| 리소스 | 7개 (gend:// URI 스킴) |
| 인증 | Bearer Token (Keycloak JWT) |
1단계: Bearer 토큰 발급
옵션 A — M2M 서비스 계정 (권장)
GenD admin 이 발급한 client_id/client_secret 으로 Keycloak client_credentials grant 토큰 발급:
export GEND_BASE_URL="https://gend.genon.ai"
export GEND_CLIENT_ID="gend-svc-mcp-claude-desktop"
export GEND_CLIENT_SECRET="<발급 모달에서 복사>"
TOKEN=$(curl -sS -X POST \
"$GEND_BASE_URL/auth/realms/gend/protocol/openid-connect/token" \
-d grant_type=client_credentials \
-d client_id="$GEND_CLIENT_ID" \
-d client_secret="$GEND_CLIENT_SECRET" \
| jq -r .access_token)
echo "$TOKEN" | pbcopy # macOS — 클립보드에 복사
토큰 수명은 realm 의 accessTokenLifespan 을 따른다 — 1800초 (30분). 만료되면 위 명령으로 재발급해 MCP 클라이언트 설정의 Authorization 헤더에 갱신한다.
accessTokenLifespan 은 realm 설정이라 운영 중 변경될 수 있다. 자동화 코드는 상수 대신 토큰 응답의 expires_in 을 사용한다 — 아래 서버 사이드 연동 참조.
MCP 용도별 클라이언트 분리 권장: gend-svc-mcp-claude-desktop, gend-svc-mcp-cursor 등 사용처별 client 를 발급하면 감사 로그에서 호출 주체 식별이 쉽다.
옵션 B — 사용자 JWT (디버깅용)
브라우저로 GenD 에 로그인한 뒤 DevTools → Application → Local Storage 에서 oidc.user:... 항목의 access_token 을 복사. 사용자 권한 그대로 MCP 호출에 적용된다.
이 방법은 토큰이 사용자 세션 만료 시 무효화되고 자동 갱신이 어렵다. 장기 운영에는 옵션 A 사용.
서버 사이드 연동 — 플랫폼에 MCP 를 내장하는 경우
아래 2~4단계는 사람이 데스크톱 클라이언트를 붙이는 시나리오다. 자사 플랫폼이 GenD MCP 커넥터를 기본 기능으로 내장하는 경우 (예: GenA) 는 설정 파일에 Bearer 토큰을 하드코딩할 수 없다 — 토큰이 30분마다 만료되므로 사람이 주기적으로 재발급해 붙여넣는 운영이 되어버린다.
이 경우 client_id / client_secret 만 시크릿 매니저에 보관하고, 토큰은 코드가 캐시 + 자동 재발급한다. 자격증명 자체는 만료가 없으므로 사람 개입이 사라진다.
import json, os, time, httpx
KC = "https://gend.genon.ai/auth/realms/gend/protocol/openid-connect/token"
MCP = "https://gend.genon.ai/mcp"
class GendMCP:
def __init__(self) -> None:
self._token: str | None = None
self._expires_at = 0.0
def _token_value(self) -> str:
# expires_in 을 그대로 신뢰 — 수명 상수 하드코딩 금지.
# 만료 30초 전 선제 재발급으로 경계 구간 401 을 예방한다.
if self._token and time.time() < self._expires_at - 30:
return self._token
r = httpx.post(KC, data={
"grant_type": "client_credentials",
"client_id": os.environ["GEND_CLIENT_ID"],
"client_secret": os.environ["GEND_CLIENT_SECRET"],
})
r.raise_for_status()
body = r.json()
self._token = body["access_token"]
self._expires_at = time.time() + body["expires_in"]
return self._token
def call(self, method: str, params: dict | None = None, _retry: bool = True) -> dict:
r = httpx.post(
MCP,
headers={
"Authorization": f"Bearer {self._token_value()}",
"Accept": "application/json, text/event-stream",
},
json={"jsonrpc": "2.0", "id": 1, "method": method, "params": params or {}},
)
if r.status_code == 401 and _retry:
# 시크릿 회전 / 시계 오차 등으로 캐시 토큰이 조기 무효화된 경우
self._token = None
return self.call(method, params, _retry=False)
r.raise_for_status()
# Accept 에 text/event-stream 을 포함했으므로 SSE 응답 가능성을 방어한다.
# 현재 GenD 는 항상 application/json 을 반환하지만, 서버가 스트리밍으로
# 전환되면 r.json() 이 디코딩 예외로 깨진다.
if r.headers.get("content-type", "").startswith("text/event-stream"):
for line in r.text.splitlines():
if line.startswith("data: "):
return json.loads(line[6:])
raise ValueError("SSE 응답에 data 프레임이 없음")
return r.json()
Accept 에 두 타입을 모두 명시하는 것은 MCP Streamable HTTP 규격을 따르는 것이다. 다만 현재 GenD 구현은 Accept 값과 무관하게 application/json 을 반환하므로 (헤더를 생략해도 200), 위 SSE 분기는 서버가 스트리밍으로 바뀔 때를 대비한 방어 코드다.
시크릿 회전 시: admin 이 UI 에서 회전하면 이전 시크릿은 즉시 무효화된다. 위 401 재시도는 토큰 만료만 복구하므로, 시크릿 자체가 바뀌면 시크릿 매니저의 값을 갱신해야 한다 (400 unauthorized_client 로 나타남).
주의: 위 예시는 os.environ 을 프로세스 기동 시 한 번만 읽는다. Secret Manager / Kubernetes Secret 의 값만 바꾸면 실행 중인 프로세스에는 반영되지 않으므로, 회전 후에는 프로세스 재시작 (kubectl rollout restart) 이 필요하다. 무중단이 필요하면 자격증명을 매 발급 시점에 다시 읽도록 (os.environ 조회를 _token_value() 안으로 이동) 구현한다.
2단계: Claude Desktop 연동
설정 파일 편집
Claude Desktop의 MCP 설정 파일을 편집합니다:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"gend": {
"url": "https://gend.genon.ai/mcp",
"headers": {
"Authorization": "Bearer <1단계에서 발급한 TOKEN>"
}
}
}
}
연결 확인
Claude Desktop을 재시작한 후, 채팅 입력창 옆에 GenD MCP 아이콘이 나타나면 연동 완료입니다.
3단계: Cursor 연동
Cursor 설정에서 MCP 서버를 추가합니다.
프로젝트 루트에 .cursor/mcp.json 파일을 생성합니다:
{
"mcpServers": {
"gend": {
"url": "https://gend.genon.ai/mcp",
"headers": {
"Authorization": "Bearer <1단계에서 발급한 TOKEN>"
}
}
}
}
Cursor를 재시작하면 MCP 도구가 활성화됩니다.
4단계: VS Code Copilot 연동
VS Code 설정(settings.json)에 MCP 서버를 추가합니다:
{
"github.copilot.chat.mcp.servers": {
"gend": {
"url": "https://gend.genon.ai/mcp",
"headers": {
"Authorization": "Bearer <1단계에서 발급한 TOKEN>"
}
}
}
}
사용 예시
MCP 클라이언트가 연결되면 다음과 같이 자연어로 GenD 데이터를 활용할 수 있습니다.
카탈로그 탐색
"GenD에서 사용 가능한 카탈로그 목록을 보여줘"
MCP 도구 list_catalogs, list_schemas, list_tables가 호출됩니다.
SQL 실행
"tpch.tiny.customer 테이블에서 고객 수를 세줘"
MCP 도구 execute_query가 호출되어 SELECT count(*) FROM tpch.tiny.customer를 실행합니다.
데이터 품질 확인
"tpch.tiny.orders 테이블의 데이터 품질 점수를 알려줘"
MCP 도구 get_quality_score가 4축 점수(완전성, 유효성, 최신성, 일관성)를 반환합니다.
리니지 추적
"orders 테이블의 데이터 흐름을 보여줘"
MCP 도구 get_lineage가 업스트림/다운스트림 테이블 관계를 반환합니다.
보안 고려사항
- MCP 도구는 SqlGuard를 통해
SELECT전용으로 제한됩니다 (DDL/DML 차단). - MCPGovernor가 모든 도구 호출을 감사 로그에 기록합니다 (M2M client 발급 시
actor_type=service,user_id=<client_id>로 식별). - 쓰기 도구(
run_intel_source,save_query,create_glossary_term)는 기본 비활성화이며,GEND_MCP_WRITE_TOOLS_ENABLED로 활성화해야 합니다. - M2M 토큰은
expires_in(30분) 후 만료. 데스크톱 클라이언트는 1단계 명령으로 재발급해 설정을 갱신하고, 플랫폼 내장 연동은 서버 사이드 연동 의 자동 갱신 패턴을 사용합니다.
MCP 서버는 토큰의 권한 범위 내에서만 동작합니다. 관리자 토큰을 MCP 에 설정하면 모든 데이터에 접근 가능하므로, 최소 권한 M2M 서비스 계정 (viewer 또는 analyst role) 을 사용하세요. M2M client 는 자동 admin 승격 없음 — 변경 작업도 안전 차단됩니다.
MCP 도구 호출은 MCPGovernor 가, REST 라우터는 realm role 가드 (require_viewer / require_analyst) 가 판정한다. 그래서 realm role 이 없는 서비스 계정도 MCP 도구는 호출되지만 같은 토큰의 REST 호출은 403 이 된다 (prod 실측 확인). MCP 만 쓸 계획이면 role 부여 없이 동작하지만, 같은 자격증명으로 REST API 도 호출할 예정이면 발급 시 viewer 또는 analyst role 을 반드시 지정한다.
관련 문서
- M2M 서비스 계정 인증 — client 발급/회전 UI
- REST API 외부 통합 — 같은 자격증명으로 HTTP 호출
- gend-cli 빠른 시작 — 같은 자격증명으로 터미널 호출
- MCP 게이트웨이
- AI 에이전트 채팅
- 접근 정책