HAL AI 채팅룸 도입(0.3.0): 운영자 콘솔 오른쪽 패널에 통합 방(첫 탭 고정) + 모델별 개별 방, 모델 연결(로그인·OAuth PKCE·API 키, 비밀은 Vault), 모델별 고유 정보(이름·역할·특성), HAL 제어·감시 스킬 문서·도구 29종(읽기 즉시 / 쓰기·고위험은 제안 → 운영자 승인(재인증·3단계 확인)), 통합 방 규칙(@이름 지정, 모델→모델 자동 1회 전달), MCP stdio 서버(읽기 전용), 개발 지시 v0.3.0(Oz), docs/HAL-AI.md, VERSION_HISTORY 0.3.0 — test/hal-ai.test.mjs RED 0/11 → GREEN 11/11, 전체 26파일 182건 통과
2026-10-28 17:41:50 +00:00
/**
* hal/ai/mcp.mjs — HAL 도구를 MCP(Model Context Protocol, stdio JSON-RPC) 서버로 내보낸다(0.3.0).
*
* 용도: 서버에 로그인된 Claude Code 같은 MCP 클라이언트(로컬 CLI 연결의 `--mcp-config`)나 운영자의 개발 도구가 HAL 상태를 같은 도구 정의로 읽게 한다.
* node hal/index.mjs mcp (ARIWEB_HAL_DATA 가 가리키는 HAL 데이터로 연다. HAL 서비스와 같은 SQLite 를 WAL 로 함께 읽는다)
HAL 0.3.2: AI 연동 편의성 + 도구 기본 설정·승인 요청 — 공급자 프리셋(Claude·ChatGPT·Gemini·OpenRouter + 기타 OpenAI 호환, Gemini 자체 API 어댑터), 사전 준비 안내, OAuth 저장 직후 로그인 창 자동(완료 페이지 postMessage·닫기, Gemini Google 프리셋, OpenRouter PKCE 키 발급), CLI 로그인용 텍스트 셸(허용 명령만 PTY, 재인증, 입력 미저장, 미로그인 시 자동 열기), 연결별 도구 정책(기본 전부)·로컬 CLI 에 HAL MCP 설정 자동 주입·MCP 설정 스니펫, MCP 쓰기·고위험 호출은 승인 요청(제안)으로 + hal_action_status/hal_actions_pending, 개발 지시 v0.3.2(Oz)·docs/HAL-AI.md §7·VERSION_HISTORY 0.3.2 — test/hal-ai-032.test.mjs RED 0/6 → GREEN 6/6, 전체 27파일 189건 통과
2026-10-29 01:43:02 +00:00
* 경계: 읽기 도구만 실행한다. 쓰기·고위험 도구는 [0.3.2] 승인 요청(ai_actions, 통합 방 카드)으로 올리고 actionId 를 돌려준다 — 운영자가 콘솔에서 승인(재인증·고위험 3단계)하면 실행되며
* 클라이언트는 hal_action_status 로 결과를 본다(MCP 경로에는 운영자 세션이 없기 때문). 임의 명령·셸 도구는 없다. stdout 에는 JSON-RPC 한 줄씩만 쓴다(로그는 stderr).
HAL AI 채팅룸 도입(0.3.0): 운영자 콘솔 오른쪽 패널에 통합 방(첫 탭 고정) + 모델별 개별 방, 모델 연결(로그인·OAuth PKCE·API 키, 비밀은 Vault), 모델별 고유 정보(이름·역할·특성), HAL 제어·감시 스킬 문서·도구 29종(읽기 즉시 / 쓰기·고위험은 제안 → 운영자 승인(재인증·3단계 확인)), 통합 방 규칙(@이름 지정, 모델→모델 자동 1회 전달), MCP stdio 서버(읽기 전용), 개발 지시 v0.3.0(Oz), docs/HAL-AI.md, VERSION_HISTORY 0.3.0 — test/hal-ai.test.mjs RED 0/11 → GREEN 11/11, 전체 26파일 182건 통과
2026-10-28 17:41:50 +00:00
* 지원 메서드: initialize · notifications/initialized · ping · tools/list · tools/call. 그 밖은 -32601.
*/
import { createInterface } from 'node:readline' ;
import { toolByName , toolDefs , runTool , toolOutputText , RISK_LABEL } from './tools.mjs' ;
import { safeError } from '../../lib/redact.mjs' ;
export function runMcpServer ( d , { input = process . stdin , output = process . stdout } = {}) {
const write = ( o ) => output . write ( JSON . stringify ( o ) + '\n' );
const reply = ( id , result ) => write ({ jsonrpc : '2.0' , id , result }); const fail = ( id , code , message ) => write ({ jsonrpc : '2.0' , id , error : { code , message } });
return new Promise (( resolve ) => {
const rl = createInterface ({ input , crlfDelay : Infinity });
rl . on ( 'line' , async ( line ) => {
if ( ! line . trim ()) return ; let m ; try { m = JSON . parse ( line ); } catch ( _ ) { return fail ( null , - 32700 , 'JSON 파싱 실패' ); }
const { id , method , params = {} } = m || {};
try {
if ( method === 'initialize' ) return reply ( id , { protocolVersion : params . protocolVersion || '2025-06-18' , capabilities : { tools : { listChanged : false } }, serverInfo : { name : 'Ariweb HAL MCP' , version : d . version }, instructions : 'HAL 운영 도구. 읽기 도구만 실행되며 쓰기·고위험 도구는 운영자 콘솔 AI 채팅룸에서 승인을 거쳐야 한다.' });
if ( method === 'notifications/initialized' || ( method && method . startsWith ( 'notifications/' ))) return ;
if ( method === 'ping' ) return reply ( id , {});
if ( method === 'tools/list' ) return reply ( id , { tools : toolDefs ( 'mcp' ) });
if ( method === 'tools/call' ) {
const tool = toolByName ( params . name ); if ( ! tool ) return reply ( id , { content : [{ type : 'text' , text : `알 수 없는 도구: ${ params . name } ` }], isError : true });
HAL 0.3.2: AI 연동 편의성 + 도구 기본 설정·승인 요청 — 공급자 프리셋(Claude·ChatGPT·Gemini·OpenRouter + 기타 OpenAI 호환, Gemini 자체 API 어댑터), 사전 준비 안내, OAuth 저장 직후 로그인 창 자동(완료 페이지 postMessage·닫기, Gemini Google 프리셋, OpenRouter PKCE 키 발급), CLI 로그인용 텍스트 셸(허용 명령만 PTY, 재인증, 입력 미저장, 미로그인 시 자동 열기), 연결별 도구 정책(기본 전부)·로컬 CLI 에 HAL MCP 설정 자동 주입·MCP 설정 스니펫, MCP 쓰기·고위험 호출은 승인 요청(제안)으로 + hal_action_status/hal_actions_pending, 개발 지시 v0.3.2(Oz)·docs/HAL-AI.md §7·VERSION_HISTORY 0.3.2 — test/hal-ai-032.test.mjs RED 0/6 → GREEN 6/6, 전체 27파일 189건 통과
2026-10-29 01:43:02 +00:00
if ( tool . risk !== 'read' ) { // [0.3.2] 실행하지 않고 승인 요청(제안)을 올린다 — 운영자가 콘솔에서 승인(재인증, 고위험은 3단계 확인)하면 실행되고 hal_action_status 로 결과를 본다
try { const a = d . ai . proposeExternal ({ source : 'mcp' , tool : tool . name , args : params . arguments || {} }); return reply ( id , { content : [{ type : 'text' , text : JSON . stringify ({ approvalRequested : true , actionId : a . id , status : a . status , risk : a . risk , riskLabel : a . riskLabel , message : ` ${ tool . name } 은(는) ${ RISK_LABEL [ tool . risk ] } 도구라 바로 실행하지 않았습니다. HAL 운영자 콘솔(통합 방)에 승인 요청을 올렸습니다 — 운영자가 승인(재인증 ${ tool . risk === 'high' ? '·3단계 확인' : '' } )하면 실행됩니다. hal_action_status(actionId) 로 결과를 확인하세요.` }) }] }); }
catch ( e ) { return reply ( id , { content : [{ type : 'text' , text : `승인 요청 실패( ${ e . code || 'error' } ): ${ safeError ( e ) } ` }], isError : true }); }
}
HAL AI 채팅룸 도입(0.3.0): 운영자 콘솔 오른쪽 패널에 통합 방(첫 탭 고정) + 모델별 개별 방, 모델 연결(로그인·OAuth PKCE·API 키, 비밀은 Vault), 모델별 고유 정보(이름·역할·특성), HAL 제어·감시 스킬 문서·도구 29종(읽기 즉시 / 쓰기·고위험은 제안 → 운영자 승인(재인증·3단계 확인)), 통합 방 규칙(@이름 지정, 모델→모델 자동 1회 전달), MCP stdio 서버(읽기 전용), 개발 지시 v0.3.0(Oz), docs/HAL-AI.md, VERSION_HISTORY 0.3.0 — test/hal-ai.test.mjs RED 0/11 → GREEN 11/11, 전체 26파일 182건 통과
2026-10-28 17:41:50 +00:00
try { const out = await runTool ( d , tool , params . arguments || {}, { operatorId : null , label : 'mcp' }); return reply ( id , { content : [{ type : 'text' , text : toolOutputText ( out ) }] }); }
catch ( e ) { return reply ( id , { content : [{ type : 'text' , text : `도구 실행 실패( ${ e . code || 'error' } ): ${ safeError ( e ) } ` }], isError : true }); }
}
if ( id !== undefined ) return fail ( id , - 32601 , `지원하지 않는 메서드: ${ method } ` );
} catch ( e ) { if ( id !== undefined ) fail ( id , - 32603 , safeError ( e )); }
});
rl . on ( 'close' , () => resolve ());
});
}