Guide · 2 of 4
가이드 · 2 / 4
Connect clients on every platform
모든 플랫폼에서 클라이언트 연결
Build each client and tell it where the server is.
클라이언트를 빌드하고 서버가 어디 있는지 알려줍니다.
Where clients look
클라이언트가 찾는 곳
Android, iOS and desktop default to 127.0.0.1:23100. Override with GEMSTONE_SERVER_HOST and GEMSTONE_SERVER_PORT (environment variable or JVM system property). The host may be host, host:port, [ipv6]:port or a full URL such as https://gem.example.com; https makes the client use wss for the chat, and a URL without a port means 80 or 443. The port value may be written 23100 or :23100; an explicit port wins over one in the host. The web client uses the protocol, host and port of the page.
Android, iOS, 데스크톱의 기본값은 127.0.0.1:23100 입니다. GEMSTONE_SERVER_HOST 와 GEMSTONE_SERVER_PORT(환경 변수 또는 JVM 시스템 속성)로 바꿉니다. 호스트는 host, host:port, [ipv6]:port, 또는 https://gem.example.com 같은 전체 URL 일 수 있습니다. https 이면 채팅에 wss 를 쓰고, 포트 없는 URL 은 80 또는 443 입니다. 포트 값은 23100 과 :23100 모두 됩니다. 명시한 포트가 호스트 안의 포트보다 우선합니다. 웹 클라이언트는 페이지의 프로토콜, 호스트, 포트를 씁니다.
The settings dialog sets the address and keeps it: open it with the user button at the top of the sidebar. A value set at launch (the variables above, or the desktop --server) wins for that run, and the dialog shows it read-only.
설정 대화상자에서 주소를 정하고 보관할 수 있습니다. 사이드바 위쪽의 사용자 버튼으로 엽니다. 실행할 때 정한 값(위의 변수, 또는 데스크톱의 --server)이 그 실행 동안 우선하며, 대화상자는 그 값을 읽기 전용으로 보여 줍니다.
If the server has GEMSTONE_API_KEY set, enter the same value in the settings dialog, or give it to the client as its own GEMSTONE_API_KEY. The dialog keeps the key in the platform's secure storage (the Keychain on iOS and macOS, the Android Keystore, DPAPI on Windows, the Secret Service on Linux), never in plain text. The key is sent as Authorization: Bearer <key> on every HTTP and WebSocket request. The browser cannot set that header on a WebSocket, so the bundled web client does not carry a key.
서버에 GEMSTONE_API_KEY 가 설정되어 있으면 같은 값을 설정 대화상자에 입력하거나, 클라이언트의 GEMSTONE_API_KEY 로 주세요. 대화상자는 키를 평문이 아니라 플랫폼의 보안 저장소(iOS 와 macOS 의 Keychain, Android Keystore, Windows 의 DPAPI, Linux 의 Secret Service)에 보관합니다. 키는 모든 HTTP 와 WebSocket 요청에 Authorization: Bearer <key> 로 실립니다. 브라우저는 WebSocket 에 그 헤더를 넣을 수 없으므로, 서버에 들어 있는 웹 클라이언트는 키를 싣지 않습니다.
Desktop
데스크톱
./gradlew :app:run
./gradlew :app:packageDistributionForCurrentOS # Dmg, Msi or Deb
The desktop app accepts the server on its command line:
데스크톱 앱은 명령줄에서 서버를 받습니다:
--server 192.168.0.10:23100 # or -s
--host 192.168.0.10 --port 23100 # or -h / -p
--help
Android
Android
./gradlew :app:installDebug
adb reverse tcp:23100 tcp:23100 # make the device's 127.0.0.1:23100 reach your machine
On Android, set the server's LAN address in the settings dialog. To reach a server on the same computer from an emulator or a USB device, adb reverse is simpler. The server listens on 127.0.0.1 by default, which is enough for this.
Android 에서는 설정 대화상자에 서버의 LAN 주소를 입력합니다. 에뮬레이터나 USB 로 연결한 기기에서 같은 컴퓨터의 서버로 가려면 adb reverse 가 더 간단합니다. 서버는 기본적으로 127.0.0.1 에서 받으며, 이것으로 충분합니다.
Serving other machines (LAN)
다른 기기에 서비스하기 (LAN)
GEMSTONE_HOST=0.0.0.0 GEMSTONE_API_KEY=change-me uv run --extra torch python -m api run server
GEMSTONE_API_KEY=change-me ./gradlew :app:run --args="--server http://192.168.0.10:23100"
GEMSTONE_HOST sets the server's bind address (host or host:port); the default is 127.0.0.1. Binding beyond loopback without GEMSTONE_API_KEY prints one warning at start-up but is allowed, as in Ollama. A browser on another machine may need its origin listed in GEMSTONE_ORIGINS. A phone on the LAN cannot be pointed at the server until Android gets an address setting; meanwhile forward a port from a machine that can reach it and use adb reverse as above.
GEMSTONE_HOST 는 서버가 받는 주소(host 또는 host:port)를 정하며 기본값은 127.0.0.1 입니다. 루프백 밖으로 열면서 GEMSTONE_API_KEY 가 없으면 시작할 때 경고를 한 번 출력하지만, Ollama 와 같게 막지는 않습니다. 다른 기기의 브라우저는 그 출처를 GEMSTONE_ORIGINS 에 적어야 할 수 있습니다. Android 에 주소 설정이 생기기 전까지는 LAN 의 휴대폰이 서버를 가리키게 할 수 없습니다. 그동안은 서버에 닿는 컴퓨터에서 포트를 전달하고 위처럼 adb reverse 를 쓰세요.
Web
웹
The web client talks to whichever host served it, so it must be served by the Gemstone server: that is what http://127.0.0.1:23100/ does. The bundle lives in api/src/main/webpack/ and is committed, so that a server checkout works without a JDK. You do not commit it yourself: after a client change reaches develop, CI rebuilds the bundle and commits it, because a local build never matches CI's byte for byte. To try a client change in your own server:
웹 클라이언트는 자신을 서빙한 호스트와 대화하므로, Gemstone 서버가 서빙해야 합니다: http://127.0.0.1:23100/ 이 바로 그것입니다. 번들은 api/src/main/webpack/ 에 있고 커밋되어 있습니다. JDK 없이도 서버 체크아웃이 동작하게 하기 위해서입니다. 번들은 직접 커밋하지 않습니다. 클라이언트 변경이 develop 에 들어가면 CI 가 번들을 다시 빌드해 커밋합니다. 로컬 빌드는 CI 빌드와 바이트 단위로 일치하지 않기 때문입니다. 내 서버에서 클라이언트 변경을 시험하려면:
./gradlew :app:wasmJsBrowserDistribution
tools/sync-web-bundle.sh # copies the production build into api/src/main/webpack/
./gradlew :app:wasmJsBrowserDevelopmentRun is handy for UI work, but its page is served by the Gradle dev server, which has no chat API behind it.
./gradlew :app:wasmJsBrowserDevelopmentRun 은 UI 작업에 편리하지만, 그 페이지는 Gradle 개발 서버가 서빙하므로 뒤에 채팅 API 가 없습니다.
iOS
iOS
Open app/src/iosMain/swift/iosApp.xcodeproj in Xcode. Status: partial. The project builds for the simulator (xcodebuild -sdk iphonesimulator, checked on 2026-10-04, #165). Its build phase runs ./gradlew :app:embedAndSignAppleFrameworkForXcode from the repository root. The app has not yet run on a simulator or a device.
Xcode 에서 app/src/iosMain/swift/iosApp.xcodeproj 를 엽니다. 상태: 부분. 프로젝트는 시뮬레이터용으로 빌드됩니다(xcodebuild -sdk iphonesimulator, 2026-10-04 확인, #165). 빌드 단계는 저장소 루트에서 ./gradlew :app:embedAndSignAppleFrameworkForXcode 를 실행합니다. 앱을 시뮬레이터나 기기에서 실행해 본 적은 아직 없습니다.