Component
Technology
Language
Notes
iOS App
SwiftUI + WKWebView
Swift
Native WebKit browser, Bonjour for mDNS
Android App
Jetpack Compose + WebView
Kotlin
Chrome DevTools Protocol for DOM access
macOS App
SwiftUI + WKWebView + CEF
Swift
Dual Safari/WebKit and Chrome/Chromium renderers, macOS 14+
Linux App
C++17 + GTK3 + CEF + Avahi
C++
Chromium-only desktop shell with optional headless mode
CLI
Node.js
TypeScript
Published as @unlikeotherai/kelpie
MCP Servers
MCP SDK
Per-platform
Browser-embedded + CLI standalone
Concern
Choice
Why
UI Framework
SwiftUI
Modern declarative UI, native performance
Browser Engine
WKWebView
Only allowed engine on iOS in most regions; native screenshot + DOM APIs. See browser-engines.md for EU/Japan/UK alternative engine support.
DOM Access
WebKit Message Handlers + evaluateJavaScript via native bridge
Calls go through WKWebView's native API; some features require ephemeral bridge scripts
Screenshots
WKWebView.takeSnapshot(with:)
Native API, no JS required
HTTP Server
Swifter or Telegraph
Lightweight embedded HTTP server for receiving commands
mDNS
NWListener + NWBrowser (Network framework)
Built into iOS — zero dependencies. Replaces deprecated NetService (iOS 16+)
MCP Server
Custom implementation over HTTP transport
MCP protocol over the same HTTP server
Networking
URLSession
Standard iOS networking
Min Target
iOS 16+
WKWebView snapshot API stability
iOS — Required Info.plist Entries
<!-- Local network access prompt (required iOS 14+) -->
<key >NSLocalNetworkUsageDescription</key >
<string >Kelpie uses the local network to receive browser automation commands from the CLI.</string >
<!-- Bonjour service types for mDNS (required for NWListener/NWBrowser) -->
<key >NSBonjourServices</key >
<array >
<string >_kelpie._tcp</string >
</array >
Without these entries, iOS will silently block local network access and mDNS advertisement.
WKWebView.evaluateJavaScript(_:) — DOM queries and reads via native bridge
WKWebView.takeSnapshot(with:completionHandler:) — viewport screenshots
WKNavigationDelegate — navigation lifecycle
WKUIDelegate — dialogs, new windows
WKWebView.scrollView — native scroll control
UIView.drawHierarchy(in:afterScreenUpdates:) — full-page screenshots
NWListener / NWBrowser (Network framework) — mDNS advertisement and discovery
Concern
Choice
Why
UI Framework
Jetpack Compose
Modern declarative UI, Material 3
Browser Engine
Android WebView (Chromium-based)
Full CDP support for DOM access
DOM Access
Chrome DevTools Protocol (CDP) via WebView.setWebContentsDebuggingEnabled
Full DOM tree via protocol — no scripts enter the page context
Screenshots
PixelCopy.request() or View.drawToBitmap()
Hardware-accelerated capture
HTTP Server
Ktor (embedded server) or NanoHTTPD
Ktor preferred — Kotlin-native, coroutine-based
mDNS
NsdManager (Network Service Discovery)
Built into Android — zero dependencies
MCP Server
Custom implementation over HTTP transport
MCP protocol over the same Ktor server
Min Target
Android API 28+ (Android 9)
CDP support in WebView
WebView.evaluateJavascript() — DOM queries via native bridge
WebView.setWebContentsDebuggingEnabled(true) — enables CDP
CDP DOM.getDocument / DOM.querySelectorAll — full DOM via protocol
CDP Page.captureScreenshot — screenshots via protocol
PixelCopy.request() — hardware screenshot fallback
NsdManager.registerService() — mDNS advertisement
NsdManager.discoverServices() — mDNS discovery
Android — CDP vs evaluateJavascript
Both paths are available. CDP is preferred for DOM operations because:
No script enters the page's JS context
Access to computed styles, layout metrics, accessibility tree
Network interception, console logs, performance metrics
Same protocol Playwright uses internally
evaluateJavascript is the fallback for simpler queries where CDP is overkill.
Concern
Choice
Why
UI Framework
SwiftUI
Matches Apple platform architecture and keeps macOS UI native
Browser Engines
WKWebView + CEF + Gecko
Runtime switching between Safari/WebKit, Chrome/Chromium, and Firefox/Gecko
Renderer Abstraction
Shared Swift protocol over all engines
Keeps one handler surface for navigation, JS, screenshots, and cookies
CEF Integration
Objective-C++ bridge over the CEF C API
Exposes Chromium safely to Swift code
Gecko Integration
Bundled Firefox runtime via CDP subprocess
Firefox binary bundled in Frameworks/KelpieGeckoHelper.app; run make gecko-runtime once to download
HTTP Server / mDNS
Network.framework
Reuses Apple-native local networking primitives on macOS
Min Target
macOS 14+
Required for the native app baseline and SwiftUI app lifecycle
WKWebView.evaluateJavaScript(_:) — WebKit DOM queries and reads
WKHTTPCookieStore — WebKit cookie access and migration
CEF C API via Objective-C++ bridge — Chromium navigation, JS, cookies, screenshots
NSViewRepresentable / NSWindow integration — embeds the active renderer in SwiftUI
NWListener / NWBrowser (Network framework) — local HTTP serving and mDNS advertisement
Concern
Choice
Why
Runtime
Node.js 20+
LTS, native fetch, stable ESM
Language
TypeScript 5+
Type safety, LLM-readable code
CLI Framework
Commander.js
Mature, lightweight, great help generation
mDNS Discovery
bonjour-service
Pure JS Bonjour/mDNS — works on macOS, Linux, Windows
HTTP Client
Native fetch
No dependencies, built into Node 20+
MCP Server
@modelcontextprotocol/sdk
Official MCP SDK for TypeScript
Output Formatting
chalk + cli-table3
Terminal colors + table formatting
Build
tsup
Fast bundler for CLI distribution
Package Manager
pnpm
Workspace-aware, fast, disk-efficient
Publishing
npm as @unlikeotherai/kelpie
Scoped under org
packages/
cli/ # @unlikeotherai/kelpie
src/
commands/ # Commander command definitions
discovery/ # mDNS browser discovery
client/ # HTTP client for browser communication
group/ # Group command orchestration
mcp/ # MCP server implementation
help/ # LLM help system
bin/
kelpie.ts # Entry point
package.json
Concern
Choice
Notes
Protocol
HTTP/JSON
All browser-CLI communication over REST
MCP Transport
Streamable HTTP (SSE)
Standard MCP transport for both browser and CLI servers
mDNS Service Type
_kelpie._tcp
Service discovery identifier
mDNS TXT Records
id, name, model, platform, width, height, port, version
Device metadata for discovery
API Versioning
URL prefix /v1/
Forward-compatible
Image Format
PNG (screenshots)
Lossless, LLM-friendly
Shared Native Core
C++17 static libraries under native/
Shared protocol, state, automation, MCP, and desktop Chromium engine foundations
Monorepo
pnpm workspaces
CLI, shared types, and native app projects all in one repo
kelpie/
native/
core-protocol/ # Shared native protocol constants and enums
core-state/ # Shared native bookmark/history/console/network stores
core-automation/ # Shared handler context and renderer abstraction
core-mcp/ # Shared browser-side MCP registry
engine-chromium-desktop/ # Shared CEF-based desktop engine for Linux/Windows shells
packages/
cli/ # Node.js CLI — @unlikeotherai/kelpie
shared/ # Shared TypeScript types and constants
apps/
ios/ # Xcode project — Kelpie Browser
android/ # Android Studio project — Kelpie Browser
macos/ # Xcode project — Kelpie Browser for macOS
linux/ # Linux app shell consuming the shared desktop engine
windows/ # Windows app shell consuming the shared desktop engine
docs/ # This documentation
iOS (Swift Package Manager)
Package
Purpose
Swifter or Telegraph
Embedded HTTP server
Everything else is built into iOS SDK (WKWebView, NetService, URLSession).
Package
Purpose
Ktor Server (Netty)
Embedded HTTP server
Kotlinx Serialization
JSON handling
Material 3
UI components
WebView, NsdManager, PixelCopy are all Android SDK built-ins.
Package
Purpose
commander
CLI framework
bonjour-service
mDNS discovery
@modelcontextprotocol/sdk
MCP server
chalk
Terminal colors
cli-table3
Table formatting
tsup
Build/bundle
typescript
Language
Component
Build Command
Run Command
CLI
pnpm build
kelpie (global) or pnpm dev
iOS
Xcode build
Run on device/simulator
Android
./gradlew assembleDebug
Run on device/emulator
macOS
Xcode build
Run on Mac