Skip to main content
Glama
konraddzbik

termdesk

by konraddzbik

TermDesk

크로스플랫폼 SSH + SFTP + VNC + RDP 데스크톱 클라이언트 — 멀티탭 터미널, 스트리밍 파일 전송, 원격 데스크톱(SSH를 통한 VNC, 네이티브 RDP)을 하나의 창에서 제공합니다.

Electron React TypeScript CI License

상태: 출시 중 — SSH 터미널, SFTP, SSH를 통한 VNC, 네이티브 RDP, MCP 에이전트 접근, SSH 터널 관리자, 플릿 자동화, 터미널 프로그램 선택이 가능한 로컬 터미널(로그인 셸 / tmux / Zellij / screen / 대체 셸), Prompt Book + 예약된 Routines, 설정, 명령 팔레트, 패키징.


✨ 기능

  • 🖥️ 유연한 호스트 — 생성 시 SSH 전용, VNC 전용 또는 결합 호스트를 만들 수 있습니다. SSH와 VNC는 각각 선택 사항입니다. 순수 VNC 호스트는 직접 TCP 또는 SSH 터널 연결을 지원합니다(SSH 자격 증명 없이 터널을 시도하면 명확한 오류 표시). UI 작업, 명령 팔레트, 테스트 버튼이 호스트 종류에 맞게 조정됩니다.

  • 🖥️ 멀티탭 SSH 터미널 — 검색, 복사/붙여넣기, 크기 조정을 지원하는 xterm.js(WebGL); 동일하거나 다른 호스트에 대한 다중 병렬 세션. 터미널이 연결될 때까지 초기 출력이 버퍼링되므로 MOTD/배너가 유실되지 않습니다.

  • 📁 스트리밍 전송 큐가 있는 SFTP — 원격 파일 브라우저, 드래그 앤 드롭(재귀 폴더 업로드), 일정한 메모리를 사용하는 청크 단위 스트리밍, 취소/재시도, 저장 시 자동 업로드되는 제자리 편집.

  • 🔒 SSH를 통한 VNC — 앱 내에서 렌더링되는 noVNC, 일회용 30초 토큰으로 보호되는 루프백 WebSocket 브리지를 통해 공급됩니다. 기본 전송은 SSH forwardOut 터널이므로 포트 5900이 노출되지 않습니다. VNC 전용 호스트는 직접 모드도 지원합니다.

  • 🖥️ RDP — 인프로세스 RDCleanPath 프록시를 통해 공급되는 IronRDP WASM 클라이언트로 앱 내에서 Windows/RDP 호스트에 연결합니다(VNC 브리지와 동일한 일회용 30초 토큰, 출처 검사, TLS 종료 구조). 최초 사용 시 신뢰(TOFU) 서버 인증서 고정을 지원합니다.

  • 🔐 암호화된 볼트 — SQLite의 호스트, 그룹, 스니펫, 알려진 호스트; 비밀번호/암호문은 메인 프로세스에 도착하는 즉시 OS 키체인 기반 safeStorage로 암호화됩니다.

  • 🛡️ 호스트 키 검증 — 첫 연결 시 SHA256 지문 승인 대화상자, 동일 유형 키 변경 시 강제 차단, 알려진 호스트가 이전에 신뢰된 적 없는 키/유형을 제시하면 별도의 큰 "중간자 공격 가능성" 경고를 표시합니다.

  • 🪜 ProxyJump — 연결된 forwardOut을 통한 멀티홉 체인(user@jump:port,next).

  • 🔌 SSH 터널 관리자 — 사이드바 패널에서 로컬(-L) 포트 포워드와 동적 SOCKS5(-D) 프록시를 정의, 저장, 시작/중지할 수 있으며 실시간 상태 점 + 처리량을 표시합니다. 가능하면 열린 터미널의 연결을 재사용하며, 파괴적 작업 없음, 소유자 범위, 로깅됩니다. docs/TUNNELS.md 참조.

  • 🪟 분할 창 — 두 세션을 나란히 또는 위아래로 볼 수 있습니다(탭 또는 분할 도구 모음을 Alt-클릭). 드래그 가능한 분할선을 제공합니다. 실시간 모니터링 그리드를 위한 멀티호스트 자동화와 함께 사용하면 좋습니다.

  • 💻 로컬 터미널 — SSH 없이도 저장된 작업 디렉터리와 함께 자신의 머신에서 node-pty 셸 탭을 실행합니다. 호스트별 기본 원격 경로는 연결 시 적용됩니다.

  • 🧩 터미널 프로그램 선택 — 터미널이 열릴 때 실행할 프로그램을 선택합니다(설정 → 일반): 기본 로그인 셸, 멀티플렉서(tmux, Zellij, GNU Screen — 재시작/연결 끊김 후에도 유지) 또는 대체 셸(bash, zsh, fish, PowerShell, Nushell). 머신에서 감지된 프로그램만 선택할 수 있으며, 이 선택은 로컬 터미널과 SSH 세션 모두에 적용됩니다(원격에 있으면 실행되고, 없으면 일반 셸 사용).

  • 🚀 외부 터미널에서 열기 — 현재 디렉터리를 원하는 GUI 터미널 — Ghostty, Warp, iTerm2, kitty, Alacritty, WezTerm, GNOME Terminal, Konsole, Windows Terminal — 로 넘겨줍니다. 머신에서 감지되며 저장된 기본값(설정 → 일반)을 사용하고, ⌘K 또는 로컬 터미널 탭의 원클릭 버튼으로 실행합니다.

  • 플릿 자동화 — SSH 호스트 그룹 전체에서 스니펫 또는 명령을 한 번에 실행하고, 호스트별 실시간 스트리밍 출력을 제공합니다.

  • 🕘 활동 로그 — 연결/연결 해제, SFTP/VNC 열기, 자동화 실행의 로컬 타임라인. 메타데이터만 포함: 비밀을 담은 명령 토큰은 삭제되고 항목은 90일 후 제거됩니다.

  • 🎨 터미널 색상 구성표 — 기본 구성표 외에 Dracula, Solarized Dark, Gruvbox, One Dark, Nord가 내장되어 있어 취향에 따라 선택할 수 있습니다.

  • 🧱 사용자 지정 가능한 사이드바 — 설정 → 일반 또는 사이드바의 사용자 지정 버튼에서 왼쪽 사이드바의 각 섹션(호스트, 로컬 터미널, 작업 공간, 터널, 스니펫, Prompt Book, Routines)을 표시하거나 숨길 수 있습니다. 선택은 유지되며 기본적으로 모두 표시됩니다.

  • 🧩 Prompt Book — AI 에이전트를 위한 재사용 가능한 템플릿 프롬프트. 프롬프트는 {{variable}} 자리 표시자(선택적으로 {{name:default}} / {{name|description}})가 있는 일반 텍스트입니다. 실행하면 값을 묻고 실시간 미리 보기를 표시한 다음, 렌더링된 텍스트를 활성 터미널(SSH 또는 로컬)로 보내거나 선택한 디렉터리에서 AI 에이전트 — Claude Code, Aider, OpenCode, Codex 또는 Gemini — 로 실행합니다. 템플릿은 순수 치환(eval 없음)이며 프롬프트는 단일 따옴표 인수로 전달되므로 셸 메타문자가 무력화됩니다.

  • 🔁 Routines — "이 프롬프트이 에이전트이 디렉터리에서 실행"하는 작업을 저장하고, 요청 시 또는 일정(간격 / 매일 / cron)에 따라 실행하며, 각각 자체 실행 기록을 가집니다. Routines는 TermDesk가 열려 있는 동안 실행되며, 앱이 닫혀 있는 동안 놓친 실행은 모든 놓친 슬롯을 한꺼번에 실행하는 대신 다음 시작 시 한 번만 따라잡습니다. 무인 자동 실행은 선택 사항이며 기본적으로 꺼져 있습니다. 저장된 실행 요약은 비밀 정보가 삭제됩니다.

  • 📋 스니펫 — 활성 세션으로 보내는 저장된 명령.

  • ⌨️ 명령 팔레트⌘/Ctrl+K 퍼지 호스트 검색 + 모든 명령(터미널, SFTP, VNC, 자동화, 로그); ?를 누르면 단축키 치트 시트가 표시됩니다.

  • ⚙️ 설정 — 테마(다크 / 라이트 / 시스템, OS를 따름), 터미널 글꼴 + 색상 구성표, 마우스 오른쪽 클릭 붙여넣기 동작, SSH keepalive; 일반 JSON이며 비밀 정보는 포함하지 않습니다.

  • 🤖 AI 에이전트 접근(MCP) — Claude, Cursor, Grok 또는 모든 MCP 클라이언트가 TermDesk를 사용할 수 있습니다: 호스트 나열, 명령 실행, 플릿 전체에 분산 실행. 에이전트는 키가 아닌 손만 얻습니다 — 자격 증명은 메인 프로세스에 유지되며, 모든 작업은 호스트별 옵트인 + 승인 게이트가 적용되고 AI 활동 로그에 실시간으로 표시됩니다. 기본적으로 꺼져 있습니다. docs/MCP-INTEGRATION.md 참조.

  • 🏠 로컬 우선 — 호스트, 키, 기록이 머신을 벗어나지 않습니다. 필수 클라우드 계정이나 텔레메트리가 없습니다.

Related MCP server: SentryFrogg MCP Server

🏗 아키텍처

모든 SSH/SFTP/VNC 로직은 메인 프로세스에 있습니다. 렌더러는 완전히 샌드박스 처리되며(contextIsolation: true, nodeIntegration: false, sandbox: true) 타입이 지정되고 Zod로 검증된 IPC 계약(src/shared/ipc.ts)을 통해서만 통신합니다.

flowchart LR
    subgraph R["Renderer (sandboxed, no Node)"]
        UI["React 19 UI<br/>zustand stores"]
        XT["xterm.js<br/>terminal"]
        NV["noVNC<br/>RFB client"]
    end

    subgraph M["Main process"]
        IPC["Typed IPC<br/>Zod-validated contracts"]
        SM["SessionManager<br/>(ssh2: shell, agent,<br/>keys, ProxyJump)"]
        SF["SftpManager +<br/>TransferManager<br/>(streaming queue)"]
        WB["ws-bridge<br/>127.0.0.1, random port,<br/>single-use 30s tokens"]
        VA[("Vault<br/>better-sqlite3 + Drizzle<br/>secrets via safeStorage")]
    end

    RH[("Remote host<br/>sshd · sftp · vncserver")]

    UI <-->|"invoke/handle"| IPC
    XT <-->|"ssh:data:#lt;sessionId#gt; stream"| IPC
    IPC <--> SM
    IPC <--> SF
    SM --- VA
    SF --- SM
    NV -->|"ws://127.0.0.1:#lt;port#gt;/#lt;token#gt;"| WB
    WB -->|"variant B (default):<br/>ssh2 forwardOut → :5900"| SM
    WB -.->|"variant A (opt-in):<br/>direct TCP → :5900"| RH
    SM <-->|"SSH"| RH

"비밀은 메인에 유지" 원칙에 대한 의도적인 두 가지 예외: 저장된 VNC 비밀번호(RFB 자격 증명 핸드셰이크용)와 저장된 RDP 비밀번호(IronRDP 클라이언트용)는 메인에서 복호화되어 렌더러로 반환됩니다. 현재 둘 다 열린 탭에 바인딩되거나 속도 제한되지 않습니다 — 알려진 제한 사항 참조.

🚀 빠른 시작

TermDesk는 현재 소스에서 실행합니다. konraddzbik/termdesk에는 태그도 GitHub Releases도 없으므로 Releases 페이지에서 다운로드할 것이 아직 없습니다 — INSTALL.md 참조.

Node.js >=22.12.0npm 10+, 그리고 네이티브 모듈을 컴파일할 수 있는 C/C++ 툴체인(Xcode Command Line Tools / build-essential / Visual Studio C++ build tools)이 필요합니다. Linux에서는 잠금 해제된 OS 키링(gnome-libsecret 또는 kwallet)도 필요합니다 — TermDesk는 Electron의 안전하지 않은 basic_text 폴백을 사용하는 대신 안전하게 실패하므로, 키링이 없으면 호스트 비밀번호를 저장할 수 없습니다(SECURITY.md).

npm install        # also applies the better-sqlite3 patch + rebuilds native deps
npm run dev        # electron-vite dev server + Electron window, HMR

첫 실행: npm install && npm run dev로 사용 가능한 앱이 열립니다 — 라이선스 확인, 시트, 계정이 없습니다. npm test를 실행하기 전에 필요한 better-sqlite3 ABI 단계를 포함한 전체 개발 설정은 CONTRIBUTING.md를 참조하세요.

스크립트

설명

npm run dev

electron-vite 개발 서버 + Electron 창

npm run doctor

사전 점검: Node, 툴체인, better-sqlite3 ABI, Linux 키링

npm run build

타입 검사(TS strict) + out/ 프로덕션 빌드

npm run lint / lint:fix

biome 검사(포맷 + 린트)

npm test

vitest(단위 + 통합)

npm run test:coverage

v8 커버리지가 포함된 vitest

npm run dist

빌드 + electron-builder(dmg / NSIS / AppImage)

npm run dist는 호스트 OS용 서명되지 않은 설치 프로그램을 생성합니다(Apple Silicon macOS에서는 dist/TermDesk-<version>-arm64.dmg, 크로스 빌드된 x64 .dmg도 포함). 아무것도 게시하지 않습니다. 소스에서 설정하는 방법, 로컬 아티팩트 이름, 향후 GitHub Release가 어떻게 만들어질지는 INSTALL.md를 참조하세요.

🧪 개발 테스트 환경

단일 Docker 컨테이너가 로컬 테스트를 위한 SSH + TigerVNC를 제공합니다 — 실제 서버가 필요 없습니다:

npm run test:keys                                  # throwaway SSH keys (untracked)
docker compose -f docker-compose.test.yml up -d

서비스

엔드포인트

자격 증명

SSH

127.0.0.1:2222

testuser / testpass123, 또는 .test/에 생성된 키(test_key, test_key_enc)

VNC

127.0.0.1:5901 (직접 또는 SSH 터널을 통해 — 동일 컨테이너)

testvncpass

E2E 스모크 하네스

다섯 개의 자체 포함 엔드투엔드 스위트가 실제 Electron 앱 내부에서 실행됩니다(처음 네 개는 docker 컨테이너 대상, MCP 스위트는 외부 서비스가 필요 없음). 각각 성공 시 *_OK 마커를 출력합니다:

명령

검증 내용

확인 결과

TERMDESK_SMOKE=vault npx electron .

비밀번호가 저장 전에 safeStorage로 암호화됨; SQLite에 평문 없음; 렌더러로 반환되지 않음

VAULT_SMOKE_OK

TERMDESK_SMOKE=ssh npx electron .

비밀번호, 키, 키 + 암호화된 패스프레이즈를 사용한 실제 로그인

SSH_SMOKE_OK

TERMDESK_SMOKE=sftp npx electron .

RSS 모니터링을 통한 1 GB 업로드 + 다운로드(최고 259 MB — 300 MB 예산 미만) 및 500개 파일 폴더 업로드

SFTP_SMOKE_OK

TERMDESK_SMOKE=vnc npx electron .

직접 및 SSH 터널을 통한 RFB 핸드셰이크; 위조 토큰 연결 거부; 토큰 일회용

VNC_SMOKE_OK

TERMDESK_SMOKE=mcp npx electron .

토큰 게이트 MCP 서버가 루프백에서 시작; 위조 베어러 토큰 거부

MCP_SMOKE_OK

✅ 테스트

npm test                # unit + integration suite (vitest) — all green on main
npm run test:coverage   # v8 line coverage report into coverage/

Vitest는 jsdom(Testing Library)에서 렌더러 테스트를 실행하고 나머지는 node에서 실행합니다. 커버리지는 중요한 곳에 집중되어 있습니다 — 순수 로직은 높은 반면, 프로세스 접착 코드와 UI 셸은 단위 테스트 대신 5개의 e2e 스모크 테스트로 커버됩니다(아래 백분율은 참고용이며 고정된 값이 아닙니다 — 최신 수치는 npm run test:coverage를 실행하세요):

  • 높음(라인): shared 97.1% — 모든 프로세스가 의존하는 Zod IPC 계약 — renderer/lib 97.5%, main/store 81.4% (db, hosts-repo, settings 및 snippets-repo는 100% 또는 그에 근접), ssh-util 100%, ~/.ssh/config 파서와 그 Include 리졸버는 90%대 후반.

  • 낮음, 대신 스모크 테스트로 커버: main/ipc 핸들러 접착 코드 9.8%, session-managersftp-manager/transfer-manager 0%, vnc-manager 및 UI 셸(SftpTab, TerminalView, VncTab, 레이아웃 및 사이드바 패널)은 낮거나 0%. 이들은 프로세스 접착 코드와 Electron/DOM 셸입니다. TERMDESK_SMOKE 하네스가 실제 서버를 대상으로 이들을 종단 간 실행합니다. 엔트리 포인트와 *-smoke.ts 파일은 구성에 따라 커버리지에서 제외됩니다.

빌드 + 타입체크 + 린트가 모두 깨끗하며, 헤드 모드(headed) 개발 실행 시 오류 로그가 0줄입니다.

⌨️ 키보드 단축키

단축키

동작

⌘/Ctrl+K

명령 팔레트(퍼지 호스트 검색 + 명령)

⌘/Ctrl+T

새 세션(팔레트 열기)

⌘/Ctrl+W

활성 탭 닫기

⌘/Ctrl+F

터미널에서 검색

⌘/Ctrl+Shift+C/V

터미널에서 복사/붙여넣기

⚙️ 설정

테마(다크, 라이트 또는 시스템 — OS prefers-color-scheme를 따름), 터미널 글꼴 크기/패밀리, SSH keepalive 간격 — userData/settings.json에 일반 JSON으로 저장됩니다(비밀번호는 절대 저장되지 않음).

📡 기능 상세

SSH 터미널

  • 모든 ssh2 로직은 메인 프로세스(src/main/ssh/session-manager.ts)에 있습니다. 렌더러는 타입이 지정된 스트림 API만 볼 수 있습니다. 출력은 ssh:data:<sessionId>로 스트리밍되며, 초기 출력은 터미널이 연결될 때까지 버퍼링됩니다.

  • 인증: 볼트 비밀번호(keyboard-interactive 폴백 포함), 개인 키(+ 암호화된 패스프레이즈) 또는 SSH 에이전트(SSH_AUTH_SOCK, Windows OpenSSH 파이프). 비밀번호는 연결 시에만 복호화됩니다.

  • 호스트 키: 첫 연결 시 SHA256 지문 승인 대화상자가 표시되고 known_hosts 테이블에 저장됩니다. 불일치 시 연결이 강제 차단됩니다.

  • 체인 방식의 forwardOut을 통한 ProxyJump 체인(user@jump:port,next); keepalive 15초.

SFTP

  • SFTP 세션은 동일 호스트에 대한 열린 터미널의 활성 SSH 연결을 재사용하며(두 번째 로그인 없음), 전용 셸 없는 연결로 폴백합니다.

  • 전송은 청크 단위로 스트리밍되며(일정한 메모리 — 300 MB RSS 미만에서 1 GB 검증), 취소/재시도가 가능합니다. 폴더 드롭은 구조를 유지한 채 재귀적으로 업로드됩니다.

  • 제자리 편집은 임시 파일로 다운로드하고 OS 편집기를 연 다음 저장 시 자동 업로드합니다.

VNC

  • noVNC는 렌더러에서 렌더링됩니다. 랜덤 포트의 127.0.0.1에 바인딩된 메인 프로세스 브리지와 WebSocket으로 통신합니다. 모든 연결에는 일회용 30초 토큰이 필요합니다 — 다른 로컬 프로세스는 브리지를 사용할 수 없습니다(따라서 CSP의 ws://127.0.0.1:*).

  • 기본 전송은 SSH forwardOut 채널입니다(변형 B — 포트 5900이 노출되지 않음). 호스트에 대한 활성 터미널 연결이 있으면 이를 재사용합니다. 일반 TCP(변형 A)는 호스트별로 선택 사항입니다.

  • 저장된 VNC 및 RDP 비밀번호는 메인에서 복호화되어 각각의 클라이언트를 위해 렌더러로 반환됩니다 — "비밀번호는 메인에 유지" 원칙의 문서화된 두 가지 예외입니다.

  • 도구 모음: 로컬 배율 / 원격 크기 조정 토글, 클립보드 붙여넣기, Ctrl+Alt+Del, 전체 화면, 재연결(각 재연결 시 새 토큰 + 터널을 프로비저닝).

볼트

  • 호스트, 그룹, 스니펫 및 known_hosts는 앱의 userData 디렉터리 아래 SQLite(better-sqlite3 + Drizzle)에 저장됩니다.

  • 비밀번호/패스프레이즈는 도착하는 즉시 메인 프로세스에서 safeStorage(OS 키체인 키)로 암호화됩니다. 암호문 블롭만 데이터베이스에 닿으며, 비밀번호는 렌더러로 다시 전송되지 않습니다.

  • ~/.ssh/config 가져오기는 Host/HostName/Port/User/IdentityFile/ProxyJump를 파싱하고, Include 지시문을 해석하며(틸드/상대/절대 경로 및 글로브, 순환/깊이/크기 가드 포함), Host */와일드카드 기본값을 OpenSSH의 first-obtained-wins(먼저 얻은 값 우선) 순서를 사용하여 구체적인 호스트에 병합합니다.

🔐 보안 체크리스트

  • contextIsolation: true, nodeIntegration: false, sandbox: true — 렌더러와 프리로드는 Node를 전혀 사용하지 않습니다.

  • 메타 태그를 통한 엄격한 CSP: script-src 'self', unsafe-eval 없음, 원격 모듈 없음. connect-src'self'와 루프백 WebSocket(토큰 게이트 VNC 브리지)만 허용합니다. 개발 전용 완화는 드리프트(설정 이탈) 시 명시적으로 실패하는 Vite 플러그인을 통해 이루어집니다.

  • webSecurity: true; 내비게이션 출처 검사; window.open 거부(외부 https: → 시스템 브라우저); <webview> 차단; 권한 요청은 기본적으로 거부.

  • 모든 IPC 페이로드는 Zod로 검증됩니다(src/shared/ipc.ts가 단일 계약). invoke 결과는 IpcInvokeMap을 통해 종단 간 타입이 지정됩니다.

  • 비밀번호(SSH/VNC 비밀번호, 키 패스프레이즈)는 도착하는 즉시 메인 프로세스에서 safeStorage로 암호화됩니다. 암호문만 저장되며, 복호화는 연결 시 이루어지고 참조는 즉시 해제됩니다. TERMDESK_SMOKE=vault로 검증됨. 문서화된 두 가지 예외: VNC 및 RDP 비밀번호는 프로토콜 클라이언트를 위해 렌더러로 전달됩니다(알려진 제한 사항 참조).

  • IPC를 통과하는 오류는 정화됩니다(첫 줄만, 스택/경로 없음). 비밀번호는 절대 로깅되지 않습니다.

  • 세션, SFTP 핸들, 전송 및 호스트 키 프롬프트는 이를 생성한 WebContents에 소유자 범위(owner-scoped)로 지정되며, 해당 WebContents가 파괴되면 함께 정리됩니다.

  • 호스트 키: 첫 연결 시 SHA256 지문 승인, 불일치 시 강제 차단 — 최종 대상 및 모든 ProxyJump 홉에 대해 적용.

  • 활동 로그는 메타데이터 전용: OS 사용자 이름, 비밀번호가 포함된 명령 토큰은 마스킹(redacted), 90일 후 삭제.

  • 선택적 마스터 비밀번호(Argon2id 파생 2차 암호화 계층) — 연기됨, 향후 개선 사항으로 추적 중.

전체 보안 모델, 알려진 제한 사항 및 취약점 공개 정책은 SECURITY.md를 참조하세요.

📂 프로젝트 구조

src/
  main/                  # Electron main process — all SSH/SFTP/VNC logic lives here
    ipc/                 # IPC handlers per domain (ssh, sftp, vnc, hosts, …)
    ssh/                 # session-manager, ssh-config-parser, ssh-util (+ smoke)
    sftp/                # sftp-manager, transfer-manager, edit-watch (+ smoke)
    vnc/                 # ws-bridge, vnc-manager (+ smoke)
    store/               # Drizzle + better-sqlite3, secrets (safeStorage), settings
  preload/               # contextBridge — typed, minimal API surface (window.api)
  renderer/              # React UI (no Node access)
    components/{layout,hosts,terminal,sftp,vnc,snippets,ui}/
    hooks/  stores/  lib/
  shared/                # IPC channel contracts + Zod schemas shared by all processes

🗺 알려진 제한 사항 / 로드맵

  • 마스터 비밀번호 — 볼트 위의 선택적 Argon2id 파생 2차 암호화 계층; 연기됨.

  • Playwright 스모크 테스트(앱 실행 → 호스트 추가 → 모의 연결) — 연기됨. 현재는 5개의 TERMDESK_SMOKE 하네스가 e2e를 커버합니다.

  • ~/.ssh/config 가져오기Match 블록과 토큰 확장(%h/%p)은 여전히 건너뜁니다. 클라우드 제공업체 인벤토리 가져오기(AWS/GCP)는 구현되지 않았습니다.

강화 로드맵은 SECURITY.md를 참조하세요.

🔧 네이티브 모듈 참고 사항

  • better-sqlite3는 Electron의 V8에 맞춰 컴파일하려면 소스 패치가 필요합니다(아직 업스트림 프리빌드 없음) — npm installpatch-package를 통해 자동 적용됩니다(patches/better-sqlite3+12.10.0.patch).

  • cpu-features(선택적 ssh2 네이티브 의존성)는 불필요한 네이티브 빌드를 피하기 위해 package.json에서 noop2로 재정의됩니다. ssh2는 순수 JS 경로로 폴백합니다.

🤝 기여

이슈와 풀 리퀘스트를 환영합니다. 외부인 설치, 패키지 및 기여자 설정에 대한 제공 계획은 docs/OSS-DELIVERY-PLAN.md에 있습니다. CONTRIBUTING.md에는 개발 설정 — 그렇지 않으면 오후를 날리게 할 두 가지 네이티브 모듈 함정을 포함 — 새 코드가 지켜야 할 불변 조건, 그리고 PR 전 체크리스트가 있습니다. 기여는 인바운드=아웃바운드 MIT입니다: CLA 없음, 저작권 양도 없음.

참여는 행동 강령의 적용을 받습니다. 보안 문제는 SECURITY.md의 비공개 채널로 제출하며, 공개 이슈로 올리지 마세요.

📄 라이선스

이 저장소의 소스MIT 라이선스로 배포됩니다 — LICENSE 참조. 저작권 고지와 라이선스 전문이 함께 전달되는 한 상업적 용도를 포함하여 사용, 수정, 재배포할 수 있습니다.

Releases 페이지에 프리빌드 설치 프로그램이 있는 경우 해당 바이너리는 EULA.txt의 적용을 추가로 받습니다. 현재 GitHub Releases는 없으므로 이 소스에서 직접 만든 빌드는 LICENSE만 적용됩니다.

이 클라이언트에는 라이선스 검사, 시트 활성화 또는 계정이 없습니다. 상용 라이선스 하위 시스템은 소스 공개 시 제거되었으므로, 이 저장소에서 빌드하는 것은 전체 애플리케이션입니다.

이 경계는 여기에 설명된 것에 그치지 않고 코드로 강제됩니다. 최초 실행 EULA 프롬프트는 프로젝트 자체 릴리스 빌드에만 컴파일되므로, 포크의 npm run dist, 배포판 패키지 또는 직접 만든 설치 프로그램에서는 표시되지 않습니다.

타사 의존성은 각자의 라이선스를 유지하며, 이는 THIRD-PARTY-NOTICES.md에 나열되어 있습니다. 하나는 언급할 가치가 있는 의무가 있습니다: @novnc/novnc는 MPL-2.0이며 이 저장소는 이를 패치합니다(patches/@novnc+novnc+1.7.0.patch). 따라서 해당 수정 사항은 나머지 소스와 함께 MPL-2.0으로 여기에 게시됩니다.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables SSH interactive session management through MCP, supporting commands, menus, and session lifecycle operations.
    1
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that provides SSH tools (read-only probes and arbitrary exec) to a fleet of hosts outside Kubernetes, with an inventory-based allowlist and key-based authentication.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/konraddzbik/termdesk'

If you have feedback or need assistance with the MCP directory API, please join our Discord server