Gate opens a portal to AI coding CLIs (Claude Code, OpenAI Codex) on remote servers — code from anywhere, on any device.
Waiting in line, on the couch, on the train — pull out your phone and pick up right where you left off. Gate bridges your browser to CLI sessions over SSH, so your coding environment is always one tap away.
Browser (React) ◄──WebSocket──► Node.js Backend ◄──SSH──► Remote Server (Claude / Codex CLI)
![]() Planning mode |
![]() Interactive questions |
![]() Chat with Claude |
![]() Command execution |
- Code from anywhere — Start on your desktop, pick up on your phone. Sessions persist across devices via SSH and CLI resume.
- Attach to existing sessions — Already running a CLI in a terminal? Gate finds its transcript and resumes right where you left off.
- Clean chat UI — Terminal output parsed into markdown messages, collapsible tool cards, syntax-highlighted code blocks, and scrollable tables.
- Multi-server, multi-session — Manage several remote servers with multiple sessions each. Swipe or tap to switch.
- Live plan tracking — Checklists auto-extracted from Claude's output into a side panel. Check off steps, edit plans, send them back for execution.
- Transcript sync — Catch up on work done outside Gate by syncing the transcript from the remote CLI session.
- Responsive everywhere — Three-column desktop, drawers on tablet, bottom sheets and swipe gestures on mobile. Notch-safe.
- Multi-CLI support — Works with Claude Code and OpenAI Codex CLI. Switch between CLI tools within a session with automatic context sync. Provider sessions are preserved — switching back resumes your previous conversation, not a new one.
- Switch Chat — Start a fresh CLI conversation or resume a previous one within the same session. Messages are scoped per CLI session so switching gives you a clean view.
- Persistent history — SQLite-backed chat history survives reconnects and server restarts.
- Node.js >= 20
- A remote server with SSH access and at least one of:
- Claude Code CLI — run
claudeonce on the server to complete authentication - OpenAI Codex CLI — run
codexonce on the server to complete authentication
- Claude Code CLI — run
npm i -g @marukohe/gate
gateOpen http://localhost:3030 in your browser. Data is stored in ~/.gate/.
CLI options:
gate --port 8080 # custom port (default: 3030)
gate --host 127.0.0.1 # bind address (default: 0.0.0.0)
gate --data-dir /my/data # custom data directory (default: ~/.gate)Open the app → click Add Server → fill in your SSH credentials (password or private key). Set a default working directory for new sessions.
git clone https://github.com/Marukohe/Gate.git gate
cd gate
npm install
npm run devThe client runs on http://localhost:5173 (proxies API/WS to the server on port 3030).
| Command | Description |
|---|---|
npm run dev |
Start client + server in parallel |
npm run dev:client |
Vite dev server only (port 5173) |
npm run dev:server |
Express + WS server only (port 3030) |
npm run build |
Build both client and server |
npm run start |
Start production server |
cd server && npx vitest run |
Run server tests |
cd server && npx tsc --noEmit |
Type-check server |
gate/
├── client/ # React frontend
│ └── src/
│ ├── components/
│ │ ├── chat/ # ChatView, SessionBar, MessageBubble, ToolActivityBlock,
│ │ │ # ChatInput, ProviderSwitcher, ResumeChatDialog, BranchSwitcher
│ │ ├── layout/ # AppShell, Sidebar, TopBar
│ │ ├── plan/ # PlanPanel, PlanStepItem
│ │ ├── plan-mode/ # PlanModeOverlay, PlanModeQuestion, PlanModeThinking
│ │ ├── server/ # ServerDialog
│ │ └── ui/ # shadcn/ui components
│ ├── hooks/ # use-websocket, use-swipe
│ ├── stores/ # Zustand stores (server, session, chat, plan, plan-mode, ui)
│ └── lib/ # Utilities (plan-parser, server-utils, notification)
├── server/ # Node.js backend
│ └── src/
│ ├── index.ts # Express entry point
│ ├── db.ts # SQLite (servers, sessions, messages)
│ ├── ssh-manager.ts # SSH connection pool + CLI channel management
│ ├── ssh-browse.ts # Remote directory browsing
│ ├── ws-handler.ts # WebSocket server
│ ├── routes/ # REST API
│ ├── providers/
│ │ ├── types.ts # CLIProvider interface, OutputParser, ParsedMessage
│ │ ├── registry.ts # Provider registration and lookup
│ │ ├── claude/ # Claude Code CLI provider
│ │ └── codex/ # OpenAI Codex CLI provider
│ └── __tests__/ # Vitest test suites
└── docs/ # Design documents
Client: Vite · React 19 · TypeScript · Tailwind CSS · shadcn/ui · Zustand
Server: Express 5 · ws · ssh2 · better-sqlite3 · TypeScript
Testing: Vitest
Client → Server:
Server → Client:
{ "type": "message" | "status" | "history" | "sessions" | "git-info", "serverId": "...", ... }
{ "type": "cli-sessions", "serverId": "...", "sessions": ["..."] }| Breakpoint | Layout |
|---|---|
| Desktop (≥1024px) | Sidebar + Chat + Plan panel (3-column) |
| Tablet (768–1023px) | Chat fullwidth, sidebar/plan as drawers |
| Mobile (<768px) | Fullscreen chat, bottom sheet for servers, swipe to switch sessions |
Named after Steins;Gate — the anime where messages travel through time to change the worldline. Here, your messages travel through SSH to reach Claude on a remote server, opening a gate between any device and your coding environment.
MIT




{ "type": "connect" | "input" | "disconnect", "serverId": "...", "sessionId": "...", "text": "..." } { "type": "switch-provider", "serverId": "...", "sessionId": "...", "provider": "codex" } { "type": "reset-conversation" | "resume-cli-session", "serverId": "...", "sessionId": "...", "claudeSessionId": "..." } { "type": "list-cli-sessions", "serverId": "...", "workingDir": "...", "provider": "claude" }