Bern MCP server
2026년 11월 13일 커밋단일 선언을 통해 SwiftUI, WinUI 3, GTK 4, Jetpack Compose, WebAssembly용 네이티브 UI로 컴파일하며 MCP 지원을 내장한 Rust 프레임워크입니다.
다른 이름 AimesSoft/Bern
- 스타
- 17
- Tools
- —
- 다운로드, 30일
- —
- 최신 버전
- —
- 마지막 커밋
- 2026년 11월 13일
- 라이선스
- MIT
Bern MCP란?
Bern은(는) MCP server입니다. 단일 선언을 통해 SwiftUI, WinUI 3, GTK 4, Jetpack Compose, WebAssembly용 네이티브 UI로 컴파일하며 MCP 지원을 내장한 Rust 프레임워크입니다.
프로젝트 README에서 생성된 요약
Bern MCP server 정보
Bern는 단일 Rust 선언으로 여러 플랫폼을 위한 네이티브 사용자 인터페이스를 구축할 수 있게 해줍니다. 개발자는 코드를 한 번만 작성하면 macOS 및 iOS용 SwiftUI, Windows용 WinUI 3, Linux용 GTK 4, Android용 Jetpack Compose, 웹용 WebAssembly로 컴파일할 수 있습니다. 많은 크로스 플랫폼 프레임워크와 달리 데스크톱 및 모바일 기기에서 JavaScript 엔진이나 임베디드 브라우저를 사용하지 않으므로, 모든 버튼과 슬라이더가 표준 플랫폼 컨트롤로 유지됩니다.
이 프레임워크는 내장된 MCP 지원을 통해 AI 통합에 특화되어 설계되었습니다. AI 에이전트는 시각적 인식이나 가상 클릭에 의존하는 대신, ui_inspect 및 ui_activate와 같은 안정적인 도구 호출을 통해 애플리케이션과 상호작용합니다. 이를 통해 에이전트는 인터페이스의 실제 구조와 의미를 읽을 수 있습니다. 또한 컴파일러는 번역 누락이나 불완전한 레이아웃과 같은 일반적인 AI 코딩 오류를 컴파일 타임 에러로 변환하여 방지하는 엄격한 규칙을 적용합니다.
활용 사례
- 1멀티 플랫폼 네이티브 UI 생성SwiftUI, WinUI 3, GTK 4, Jetpack Compose, WebAssembly로 컴파일되는 단일 인터페이스 선언을 생성합니다.
- 2AI 에이전트 상호작용 활성화AI 클라이언트가 MCP 도구를 통해 안정적인 이름과 역할을 사용하여 애플리케이션 요소를 제어할 수 있도록 합니다.
- 3불완전한 AI 생성 코드 방지컴파일러를 사용하여 개발 중 AI가 누락할 수 있는 번역이나 레이아웃 기능을 잡아냅니다.
- 4MCP를 통한 애플리케이션 구조 검사픽셀 인식에 의존하는 대신 AI 에이전트에게 UI 구성 요소의 구조화된 뷰를 제공합니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
자동 검사
2026년 11월 14일에 실행됨전체 보고서 →아직 인증되지 않았습니다. 서버는 80점 이상의 점수, 심각한 결함 없음, 그리고 검사에 충분한 데이터를 갖추어야 합니다. 검사 방식 · 점수를 높이기 위해 수정할 항목
- 소스 저장소 연결 및 접근 가능aimessoft/bern is public and reachablegithub.com/aimessoft/bern ↗통과
- 패키지가 이 저장소를 소스로 명시검사되지 않음
- 빌드 출처(Sigstore 증명)검사되지 않음
- 오픈 소스 라이선스 (OSI)MITspdx.org/licenses/MIT.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-11-13github.com/aimessoft/bern ↗통과
- OpenSSF Scorecard검사되지 않음
- 패키지 이름이 인기 패키지와 유사하지 않음검사되지 않음
- 패키지 및 해당 종속성에 중요한 보안 권고 없음검사되지 않음
- 모델에 대한 숨겨진 지침 없음0 tool descriptions and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨검사되지 않음
- 원격 엔드포인트가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기Why Bern
Who uses Bern
Built for AI
Writing code: what the AI forgets, the compiler remembers
AI rarely gets interface code wrong; it leaves things out. A feature is added without an entry in the compact layout, a new string is written in one language only, a callback sidesteps the commands. Elsewhere these wait for a user to find them; in Bern they do not compile. The stricter the rules, the harder it is for an AI to hand over half a job:
Errors are written for people and for agents alike: a code, a reason and a location, so an agent can fix them and build again on its own. Two real runs on the showcase: the first with an English translation deleted, the second, after restoring it, with the compact layout's "Change Clip" menu removed:
$ bern check
error[B102]: Missing translation
Missing language: en
Required languages: zh-Hans, en
--> showcase-ui/src/pages.rs:13:31
$ bern check
error[B201]: Feature missing in adaptive layout
Contract: MediaFeature
Feature: Clip
compact: missing
--> showcase-ui/src/media.rs:14:5
Every build also writes a full feature coverage report per target (features.json) that lists what is covered, exempt or only manually guaranteed.
Using the app: meaning, not pixels
In most frameworks, letting an AI operate a desktop app means screenshots, recognition, coordinates and synthetic clicks. A Bern app ships with an MCP server: every control has a stable name and role, the agent reads structure, its actions take the same code path as a user's click, and the app answers with what actually happened.
$ showcase ui inspect # the agent reads meaning, not pixels
[{ "target": "controls_page.sync", "role": "switch", "label": "Sync", "value": "false", "enabled": true, … }, …]
$ showcase ui set-bool --target controls_page.sync --value true
$ showcase window close --window settings#1
{ "outcome": "ConfirmationRequired", "message": "Do you want to save the display name?",
"decisions": ["Save", "Discard", "Cancel"], "confirmation": "settings#1:c1", … }
$ showcase window confirm-close --window settings#1 --confirmation settings#1:c1 --decision Save
{ "outcome": "Rejected", "reason": "save_failed: invalid_name: a display name has 1 to 40 characters …" }
The same operations are MCP tools for agents (ui_inspect, ui_activate, window_close, …), and each business command is a tool too (for example showcase_set_display_name). When a button is disabled, blocked by a dialog or missing, the agent gets a clear error code rather than a click that does nothing.
Measured
- Subject: the release showcase (6 pages, a main and a settings window, a video player), measured on 2026-10-11, median of at least 3 runs.
- macOS: Apple M4, 16 GB, macOS 27.0.1. Memory is the physical footprint from
footprint, the measure of Activity Monitor's Memory column. - Windows: Intel Core i5-13490F, 32 GB, Windows 11 25H2. Memory is the private working set, the measure of Task Manager's Memory column.
- Launch time: from starting the process until the command line sees a visible native window, including engine start and the local control channel.
- The Windows numbers are the WinUI 3 front end (measured with Windows App Runtime 1.8; builds now use 2.x). Without the runtime, the same program falls back to the system XAML: 0.54 s, 19 MB. Neither needs .NET or the VC++ runtime; the app folder holds the executable and a 400 KB bootstrapper DLL.
More
- Video:
Videoplays on AVFoundation, Windows Media Foundation, GStreamer, Media3 on Android or HTML media, with a command-driven control bar and players that outlive a page. - Async queries:
Querysubscriptions with loading, empty, failure and refresh states; only the latest answer is shown. - Adaptive layouts: layouts for
compact,medium,expandedandlarge, chosen by the space a view actually gets; expressions read the window's size too, for margins that grow with it. - Typed navigation: sidebars, push navigation with typed routes, tabs, toolbars and menus.
- Feature contracts: declare which features a component must cover in each layout; the compiler proves the coverage.
- Bundled resources: files declared in
Bern.toml, checked at build time and located by name at runtime. - Images and layout:
Imageshows bundled pictures, HDR ones (PQ and HLG PNGs, JPEGs with a gain map) in HDR where the display can, and an undeclared one fails to compile;Gridadds and drops columns with the width,Stacklayers views with nine alignments,Progressshows a bar or indeterminate progress. - Style overrides and motion: controls keep the platform look by default; for one design everywhere,
style!declares app-wide overrides, spring motion, appear and disappear transitions, staggered entrances and shared elements, and an override a target cannot show fails the build (on all five front ends). - Drawing and placing by fraction:
Canvasdraws shapes, data curves and check patterns in semantic colors, andTextcan carry a highlight mark;Railputs elements at fractions that come from state, for timelines, ticks on a progress bar or a fill that grows. - Media app components: a sidebar footer, toolbar search with results, an inspector, toasts, split buttons and popover buttons holding any content, buttons with content that reveal more on hover, shortcuts, picking and dropping files, scroll snapping, pinch and drag to set a value, on all five front ends.
- Reading the files users hand you: for a file the user picked, dropped or opened with the app, the engine gets its name and bytes with
MediaSource::file_name()andopen(), the same for a local path, an Androidcontent://document or a page'sblob:file. - Modular apps: an app is a shell and modules, each with its own protocol, engine, interface and translations, switchable at runtime;
bern new --moduleadds one, so several people and AIs can work side by side (verified on macOS and Android).
How it works
flowchart LR
subgraph app["Your application (Rust)"]
P["Protocol<br/>types · state · commands"]
U["UI declarations<br/>component + ui!"]
E["Engine<br/>plain Rust"]
end
P --> C{{"bern build<br/>compiler + IR"}}
U --> C
C --> S["SwiftUI<br/>macOS · iOS"]
C --> W["WinUI 3<br/>Windows"]
C --> G["GTK 4<br/>Linux"]
C --> A["Jetpack Compose<br/>Android"]
C --> B["DOM + WASM<br/>Web"]
E <--> K[["Command catalog"]]
K <--> N["Native UI"]
K <--> L["App CLI"]
K <--> J["JSON channel"]
K <--> M["MCP server"]
- Protocol –
#[bern::protocol]declares value types, the read-only state and the command and query traits. - Engine – implements those traits in ordinary Rust; it never sees a window, a control or a transport.
- Interface –
#[component]functions whose body is aui!declaration. The compiler reads them into a shared intermediate representation, and each target module generates native code from it. Adding a target never touches the parser, the IR or your business logic.
A taste of Bern
1 · Protocol: types, state and commands
#[bern::protocol(namespace = "counter", version = 1)]
pub mod counter {
use bern::prelude::*;
#[state]
pub struct State {
pub count: i64,
}
#[commands]
pub trait Commands {
/// Add to the count.
fn add(&mut self, by: i64) -> Result<(), CommandError>;
}
}
2 · Engine: plain Rust, no UI
use bern::CommandError;
pub struct Counter {
state: counter::State,
}
impl Default for Counter {
fn default() -> Self {
Self { state: counter::State { count: 0 } }
}
}
impl counter::Commands for Counter {
fn add(&mut self, by: i64) -> Result<(), CommandError> {
self.state.count += by;
Ok(())
}
}
impl counter::Engine for Counter {
fn state(&self) -> &counter::State {
&self.state
}
}
3 · Interface: a ui! declaration
#[component]
pub fn counter_view(app: counter::Client) -> impl View {
ui! {
Form {
Text(content: tr! {
"zh-Hans" => "已计数 {n} 次",
"en" => "Counted {n} times";
n: app.count
})
Button(
id: add,
label: tr! { "zh-Hans" => "加一", "en" => "Add one" },
prominence: prominent
) => app.add(1)
}
}
}
4 · Everyone drives the same engine
counter ui inspect
counter ui activate --target counter_view.add
counter counter add --by 5
counter-mcp # the same catalog for AI agents
Bern.toml declares languages, theme, sources, bundled resources and targets. See the full showcase: a sidebar app with text styles, buttons, switches, sliders, text fields, an engine-backed search, list-to-detail navigation, video, and a settings window with tabs and a close confirmation. The planner is a modular app with style overrides, motion and Canvas. The gallery shows the media app components: a poster wall that enters in turn, a timeline placed by fraction, a volume popover, margins and layouts that follow the four sizes, and a dropped video whose name, format and size the engine reads from the file.
Platforms
Implementation notes: macOS · iOS · tvOS · Windows · Linux · Web and WebUI · Android; the next platforms are in the adaptation specs.
Omitting the UI technology picks the platform default; an unavailable default fails loudly instead of silently switching to another stack.
Windows and iOS each have two front ends
These two platforms span more system versions than one UI framework reaches, so the same declaration generates two front ends for each. By default both go into one package and the app chooses as it starts, by the system it finds. Neither the user nor the app's code has to do anything.
| Platform | Front end | Name in frontends |
Runs on |
|---|---|---|---|
| Windows | WinUI 3 | winui3 |
Systems with Windows App Runtime 2, with Mica and the Windows 11 look |
| Windows | The system XAML, through XAML Islands | xaml-islands |
Every other Windows 10 and 11, with no runtime to install |
| iOS | SwiftUI | swiftui |
iOS 17 and later; every Apple target shares this front end |
| iOS | SwiftUI for iOS 16 | swiftui-16 |
iOS 16, rewritten from the same generated code |
To keep only one, name it:
[targets.windows]
frontends = ["winui3"] # asks to install the runtime on a system without it
[targets.ios]
frontends = ["swiftui"] # iOS 17 and later
With both iOS front ends, packages = "separate" makes one .ipa of each. The Windows and iOS implementation notes give the rules of the choice, and what is reduced on iOS 16.
Compared with other cross-platform frameworks
Every framework answers the same question: how does one codebase become the interface on each platform? The answers differ, and so do the trade-offs. What follows is based on each project's official documentation; size and memory vary a lot with versions and settings, so the comparison stays structural. Bern's own numbers are in Measured.
The first two routes give you system controls: look, accessibility, input methods and dark mode come from the system, at the cost of controls that differ a little between platforms. The other two draw the same interface everywhere, at the cost of keeping up with each platform's design and behavior yourself, or of shipping a browser.
The chart is a sketch by architecture, not a ranking: the horizontal axis is whether UI elements are the system's controls or drawn by the framework or a web page; the vertical axis is how much runtime the app carries (a browser engine, a JS engine, a rendering engine, a language runtime).
Technology
Platforms and capabilities
- Mobile: iOS and Android. React Native's desktop versions are maintained by Microsoft; uni-app also covers mini programs and HarmonyOS; Bern's Android target runs on devices and makes packages, its iOS target builds simulator apps, and iOS device packages are planned.
- Native look: the controls are the platform's own, with look, accessibility and input methods from the system. Qt Widgets and uni-app x come close and count as partly.
- Built-in MCP: an MCP server and command line that come with the framework and act on the running interface. Other frameworks can be automated from outside through accessibility APIs or test tools such as Playwright and Flutter Driver.
- Compile-time checks: a missing translation, a feature without an entry in some layout, or an entry not registered to a feature is a compiler error (see Built for AI). Other frameworks mostly find these with linters, translation tools or tests.
- Maturity: Electron and Qt are very mature; Flutter, React Native, uni-app, Tauri and Avalonia are mature; Dioxus is developing quickly; GPUI powers the Zed editor while its general-purpose components are early; Bern is an early preview.
Bern MCP 질문
Bern는 어떤 플랫폼을 지원하나요?
Bern는 macOS (SwiftUI), iOS (SwiftUI), Windows (WinUI 3), Linux (GTK 4), Android (Jetpack Compose), Web (WebAssembly)를 지원합니다.
Bern는 AI 에이전트를 어떻게 지원하나요?
Bern 앱은 MCP server를 함께 제공합니다. 모든 컨트롤은 안정적인 이름과 역할을 가지므로, 에이전트가 구조를 읽고 도구를 통해 동작을 실행할 수 있습니다.
Bern는 JavaScript 엔진을 사용하나요?
아니요, Bern은 데스크톱이나 모바일 플랫폼에서 JS 엔진 또는 임베디드 브라우저를 사용하지 않습니다.