콘텐츠로 이동

MCP 서버로서의 Revka

인프로세스 MCP 서버, 디스커버리 파일, 인증 모델을 통해 Revka의 도구 표면을 외부 CLI에 노출합니다.

Revka는 메인 데몬 내부에서 백그라운드 작업으로 Model Context Protocol(MCP) 서버를 실행합니다. 따라서 MCP 호환 클라이언트(Claude Code, Codex, OpenCode, Gemini CLI, Claude Desktop 등)는 별도의 설정을 중복하지 않고도 Revka의 모든 내장 도구 및 통합 도구 표면을 직접 활용할 수 있습니다. 이 서버는 Streamable HTTP 전송을 통해 JSON-RPC 2.0을 사용하며, 임시(ephemeral) 로컬 포트에 바인딩한 뒤 외부 도구가 자동으로 읽는 디스커버리 파일을 통해 해당 포트를 알립니다.

외부 코딩 CLI가 Revka의 도구를 호출하길 원하거나, 인프로세스 서버의 네이티브 엔드포인트를 대상으로 클라이언트를 개발 중이라면 이 페이지를 참고하세요. 이 페이지는 서버 측을 다룹니다: 데몬, 네이티브 HTTP 엔드포인트, 도구 레지스트리 계층, 세션 전체 진행 스트림, 그리고 두 헤더 인증 모델입니다. 대시보드가 사용하는 브라우저용 리버스 프록시는 MCP 프록시 & 디스커버리 API를 참고하세요. Revka를 다른 MCP 서버의 클라이언트로 사용하려면 외부 MCP 서버 연결을 참고하세요.

MCP 서버는 데몬이 부팅될 때 자동으로 시작되며 별도의 프로세스를 실행할 필요가 없습니다. 127.0.0.1의 임시 포트에 바인딩한 뒤 ~/.revka/mcp.json에 URL을 기록하므로, 호출자는 포트를 하드코딩할 필요가 없습니다. 전체 부팅 순서는 다음과 같습니다:

  1. 데몬을 시작합니다(revka daemonrevka gateway, daemon & service 참고).

  2. 데몬이 MCP 서버 작업을 생성하고, 127.0.0.1:<임시 포트>에 바인딩합니다.

  3. 서버가 { url, pid, started_at }를 담은 ~/.revka/mcp.json을 원자적으로 기록합니다.

  4. 외부 CLI가 ~/.revka/mcp.json을 읽어 세션을 생성하고 도구 호출을 시작합니다.

엔드포인트는 항상 다음 형식입니다:

http://127.0.0.1:<ephemeral>/mcp

서버는 MCP **프로토콜 버전 2024-11-05**를 알리며, initialize 응답에서 자신을 revka-mcp로 식별합니다.

디스커버리 파일 (~/.revka/mcp.json)

섹션 제목: “디스커버리 파일 (~/.revka/mcp.json)”

데몬은 시작 시 ~/.revka/mcp.json을 기록합니다. 외부 CLI와 게이트웨이 모두 이 파일을 읽어 MCP 서버의 수신 위치를 파악합니다. 페이로드 형태는 고정 계약으로, 다음 세 필드만 포함됩니다:

{
"url": "http://127.0.0.1:54500/mcp",
"pid": 12345,
"started_at": "2026-06-18T00:00:00Z"
}
필드타입설명
urlstring전체 MCP 엔드포인트 (예: http://127.0.0.1:<port>/mcp). 항상 존재합니다.
pidnumber데몬 프로세스 ID. 구버전 기록자는 생략할 수 있습니다.
started_atstringRFC 3339 시작 타임스탬프(UTC). 구버전 기록자는 생략할 수 있습니다.

신뢰할 수 있는 동작:

  • 원자적 쓰기. 파일은 동일 디렉터리의 임시 파일에 먼저 기록된 후 대상 파일 위로 이름이 변경됩니다. 따라서 동시 읽기 중에 반만 쓰인 문서가 관찰될 일이 없습니다.
  • 바인딩 전에는 부재. MCP 작업이 포트를 완전히 바인딩하기 전까지 파일이 존재하지 않습니다. 호출자는 파일 부재를 오류로 처리하지 않고 정상적으로 처리해야 합니다.
  • 종료 시 삭제. 데몬은 정상 종료 시 파일을 제거합니다.
  • 게이트웨이의 mtime 캐시. 게이트웨이는 파싱된 파일을 수정 시간을 키로 캐시합니다. 데몬이 요청 사이에 재시작되어 임시 포트가 변경될 경우, mtime 변경 이후 다음 읽기 시 자동으로 재파싱하므로 재시작 후에도 오래된 포트가 사용되지 않습니다.

인프로세스 서버는 네 개의 엔드포인트를 제공합니다. 외부 CLI는 디스커버리 파일의 URL을 사용해 이 엔드포인트에 직접 접근합니다.

메서드경로인증용도
GET/health없음활성 상태 확인 프로브.
POST/session없음세션 생성; { session_id, token, cwd } 반환.
POST/mcp두 헤더(아래 참고)JSON-RPC 2.0 엔드포인트: initialize, tools/list, tools/call.
GET/session/{session_id}/eventsAuthorization: Bearer세션별 진행 상황 SSE 스트림.

단순 활성 상태 확인 프로브입니다. 다음 내용과 함께 200 OK를 반환합니다:

{
"status": "ok",
"pid": 12345,
"uptime_seconds": 3600,
"started_at": "2026-06-18T00:00:00Z",
"protocol_version": "2024-11-05"
}

세션을 생성하고 이후 모든 /mcp 호출에 필요한 자격 증명을 반환합니다. 요청 본문은 선택 사항입니다.

POST /session
Content-Type: application/json
{ "cwd": "/home/user/project", "label": "code-cli" }
필드타입설명
cwdstring (선택)세션의 작업 디렉터리. 틸드 확장 및 정규화되며, 기본값은 데몬의 현재 디렉터리입니다.
labelstring (선택)세션의 사람이 읽을 수 있는 레이블.

응답:

{
"session_id": "<session-id>",
"token": "<session-token>",
"cwd": "/home/user/project"
}

session_idtoken 모두 보관하세요. 이 값들은 모든 /mcp 호출과 이벤트 스트림을 인증하는 데 사용됩니다.

JSON-RPC 2.0 엔드포인트입니다. 아래에 설명된 두 헤더 인증이 필요하며, 정확히 세 가지 메서드를 지원합니다:

메서드응답 타입비고
initialize일반 JSONprotocolVersion, capabilities, serverInfo({ name: "revka-mcp", version })를 반환합니다.
tools/list일반 JSON각 도구의 name, description, inputSchema와 함께 모든 등록 도구를 나열합니다. 목록은 이름 기준 알파벳 순으로 정렬됩니다.
tools/callSSE 스트림도구를 실행합니다. 도구 호출 응답 형식 참고.
POST /mcp
Authorization: Bearer <session-token>
X-Revka-Session: <session_id>
Content-Type: application/json
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }

notifications/initializednotifications/cancelled 알림은 수락되며 본문 없이 202 Accepted를 반환합니다.

세션 전체 진행 상황 SSE 스트림입니다. 자세한 내용은 세션 전체 진행 스트림을 참고하세요.

POST /mcp는 유일하게 인증이 필요한 메서드 디스패치 엔드포인트이며, 헤더를 함께 요구합니다:

Authorization: Bearer <session-token>
X-Revka-Session: <session_id>

두 값 모두 POST /session 응답에서 가져옵니다. 서버는 X-Revka-Session으로 세션을 조회하고, 제공된 bearer와 발급된 토큰을 상수 시간 비교로 대조합니다. 둘 중 하나라도 헤더가 누락되거나 비어 있거나, 쌍이 활성 세션과 일치하지 않으면 서버는 401 Unauthorized를 반환합니다.

이벤트 스트림(GET /session/{session_id}/events)은 Authorization: Bearer <session-token>만 필요합니다. 세션 ID가 이미 URL에 포함되어 있으므로 X-Revka-Session은 중복입니다.

initializetools/list와 달리, tools/call 요청은 Server-Sent Events 스트림을 반환합니다. 도구가 완료 전에 진행 상황을 내보낼 수 있기 때문입니다. 각 호출에 대해 서버는 순서대로 다음을 내보냅니다:

  1. 0개 이상의 notifications/progress 이벤트 (도구 자체의 진행 보고에서 전달됨).
  2. 도구 결과({ content, isError })를 담은 정확히 하나의 터미널 JSON-RPC 응답 이벤트.
  3. 최종 event: done.
POST /mcp
Authorization: Bearer <session-token>
X-Revka-Session: <session_id>
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "notion",
"arguments": { "action": "search", "query": "roadmap" },
"_meta": { "progressToken": 7 }
}
}

params._metaprogressToken을 제공하면, 서버는 해당 호출의 모든 notifications/progress 이벤트에 이를 재사용하여 진행 상황을 원래 요청과 연관 지을 수 있습니다. 생략하면 서버가 직접 생성합니다. 존재하지 않는 도구는 스트림 대신 일반 JSON-RPC 오류(unknown tool)를 반환합니다.

서버는 계층 방식으로 등록 도구 세트를 구성합니다. 어떤 계층을 사용할 수 있는지는 부팅 시 데몬이 연결한 상태의 양에 따라 달라집니다.

기본 레지스트리는 보안 정책과 작업 공간 경로 외에는 아무것도 필요하지 않는 약 16개의 무의존성 도구로 구성된 선별 세트입니다. 설정 로드가 실패해도 항상 사용 가능합니다:

shell file_read file_write file_edit
glob_search content_search calculator weather
git_operations http_request web_fetch web_search_tool
pdf_read screenshot image_info browser_open

데몬이 Config를 로드하면 스킬 메타 도구와 자격 증명이 있는 모든 통합이 추가됩니다:

  • 스킬 메타 도구 (설정과 함께 항상 추가됨): skills_list, skills_describe, skills_execute스킬 시스템 참고.
  • 통합 (설정된 경우에만 추가됨): notion, jira, composio, google_workspace, linkedin, microsoft365.

활성화되었지만 자격 증명이 없는 통합은 부팅 시 이유와 함께 건너뛰어집니다 (예: notion — enabled but notion.api_key / NOTION_API_KEY missing). 운영자는 도구가 등록되지 않은 정확한 이유를 확인할 수 있습니다. 통합 카탈로그도구 설정 참고서에서 설정하세요.

런타임 인식 계층 (라이브 핸들 필요)

섹션 제목: “런타임 인식 계층 (라이브 핸들 필요)”

세 번째 계층은 게이트웨이가 부팅 시 라이브 런타임 핸들을 서버에 연결해야만 등록됩니다. 이 도구들은 기본 데몬이 소유하지 않는 상태(스케줄러, 채널 맵, 프로바이더 자격 증명, 작업 공간 세션 저장소)가 필요합니다:

cron_add / cron_list / cron_remove / cron_update / cron_run / cron_runs
llm_task image_gen delegate swarm
workspace poll discord_search
sop_list / sop_execute / sop_advance / sop_approve / sop_status
sessions_list / sessions_history / sessions_send

런타임 인식 도구를 등록할 수 없을 경우 서버는 건너뜀 이유를 기록합니다 (예: cron_* — needs boot Config + scheduler, discord_search — needs discord.db Memory backend). 코딩 CLI 도구(claude_code, codex_cli, gemini_cli, opencode_cli)는 의도적으로 노출되지 않습니다. 이들은 이 데몬에 연결하는 클라이언트이기 때문입니다.

tools/call SSE 스트림에 내장된 호출별 진행 상황에 더해, 서버는 모든 진행 이벤트를 세션별 브로드캐스트 채널에 게시합니다. 세션 토큰을 보유한 구독자는 해당 세션의 모든 진행 중인 도구 진행 상황을 감시할 수 있으며, 외부 CLI가 요청을 처리하는 동안 UI가 “Revka가 현재 무엇을 하고 있는지”를 표시하는 방식이 바로 이것입니다.

GET /session/<session_id>/events
Authorization: Bearer <session-token>
Accept: text/event-stream

각 이벤트의 data: 페이로드는 JSON ProgressEvent입니다. 스트림은 클라이언트가 연결을 끊을 때 종료됩니다.

ProgressEvent는 호출별 notifications/progress 페이로드를 미러링하며, tooltimestamp 두 필드가 추가됩니다. 구독자는 진행 토큰을 원래 요청과 연관 짓지 않고도 “Notion — 10개 중 4개 (10:20:33)“와 같이 렌더링할 수 있습니다:

{
"token": 7,
"progress": 4,
"total": 10,
"message": "notion: sending request",
"tool": "notion",
"timestamp": "2026-04-17T10:20:33+00:00"
}
필드타입설명
tokennumber이벤트를 tools/call과 연관 짓는 진행 토큰.
progressnumber현재 진행 수.
totalnumber (선택)알 수 있는 경우 예상 총 단계 수.
messagestring (선택)사람이 읽을 수 있는 상태 메시지.
toolstring (선택)진행 상황을 내보내는 도구 이름 (예: notion).
timestampstringRFC 3339 타임스탬프(UTC).

진행 상황은 참고용이며, 필수가 아닙니다. 브로드캐스트 채널의 용량은 고정되어 있으며, 느린 소비자는 도구 호출을 차단하는 대신 지연된 프레임을 조용히 삭제합니다. 뒤처진 구독자는 단순히 일부 프레임을 놓치고 다음 프레임에서 따라잡습니다.

전체 흐름을 정리하면, 외부 클라이언트는 다음 순서를 따릅니다:

  1. 디스커버리. ~/.revka/mcp.json을 읽어 url(예: http://127.0.0.1:54500/mcp)을 가져옵니다. 파일이 없으면 데몬이 실행 중이지 않은 것입니다.

  2. 세션 열기. POST <host>/session을 호출하고 반환된 session_idtoken을 보관합니다.

    Terminal window
    curl -s http://127.0.0.1:54500/session \
    -H 'Content-Type: application/json' \
    -d '{ "cwd": "/home/user/project", "label": "code-cli" }'
  3. 초기화 및 도구 목록 조회. 두 인증 헤더와 함께 POST <host>/mcp를 호출합니다.

    Terminal window
    curl -s http://127.0.0.1:54500/mcp \
    -H 'Authorization: Bearer <session-token>' \
    -H 'X-Revka-Session: <session_id>' \
    -H 'Content-Type: application/json' \
    -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'
  4. 도구 호출. method: "tools/call"과 함께 POST <host>/mcp를 호출하고 event: done이 나올 때까지 SSE 스트림을 읽습니다.

  5. (선택) 진행 상황 감시. bearer와 함께 GET <host>/session/<session_id>/events를 구독하여 세션의 모든 도구 진행 상황을 추적합니다.

대시보드의 Code 탭은 지원되는 CLI(Claude Code, Codex, OpenCode, Gemini 등)에 대해 이를 자동으로 연결하며, 각 도구의 설정에 디스커버리 URL, 세션 ID, 토큰을 주입합니다. 프록시 및 터미널 주입 세부 사항은 MCP 프록시 & 디스커버리 API를 참고하세요.