Single-commit clean baseline after security scrub of niche-tells, project codenames, internal jargon, and contributor-email leaks. Contents: - 100 Rust crates (_primitives/_rust/) - 37 agent manifests (_manifests/) + generated specs (_generated/) - 67 user-invocable skills (skills/) - 33 hooks (hooks/) - Composition blocks (_blocks/) - Documentation (docs/, README.md) - TS adapter packages (_ts_packages/) - Assembler (_assembler/) - Roles (_roles/) - Templates (_templates/) - Forgejo CI (.forgejo/) Author: Denis Parfionovich <info@greendragon.info> License: see LICENSE.
81 lines
3.6 KiB
Markdown
81 lines
3.6 KiB
Markdown
# Building a single-binary `kei-mcp-server`
|
||
|
||
> KeiSeiKit v0.18 Phase 1 (exobrain) — ship the MCP server as a portable
|
||
> static binary so any machine without Node can run it off a USB drive.
|
||
|
||
## Tooling
|
||
|
||
Compile via **bun** (`bun build --compile`). Bundles the Bun runtime + JS
|
||
into one static executable — no Node, no `node_modules/` at runtime.
|
||
Requires bun `>= 1.0`. Docs (target list + flags):
|
||
[VERIFIED: https://bun.sh/docs/bundler/executables]
|
||
|
||
## Supported targets
|
||
|
||
| Platform | Arch | `--target=` | Output name |
|
||
|----------|-------|------------------------|---------------------------------------|
|
||
| Linux | x64 | `bun-linux-x64` | `kei-mcp-server-linux-x64` |
|
||
| Linux | arm64 | `bun-linux-arm64` | `kei-mcp-server-linux-arm64` |
|
||
| macOS | x64 | `bun-darwin-x64` | `kei-mcp-server-darwin-x64` |
|
||
| macOS | arm64 | `bun-darwin-arm64` | `kei-mcp-server-darwin-arm64` |
|
||
| Windows | x64 | `bun-windows-x64` | `kei-mcp-server-windows-x64.exe` |
|
||
|
||
## Local build
|
||
|
||
```bash
|
||
cd _ts_packages/packages/mcp-server
|
||
bun install
|
||
bun run build:native # host-native
|
||
bun run build:native:darwin-arm64 # explicit cross-target
|
||
```
|
||
|
||
Output lands in `dist/`. Size ~85–95 MB per binary (bundled runtime).
|
||
|
||
## Release build (CI)
|
||
|
||
`.github/workflows/release.yml` → job `build-mcp-binary` runs the 5-target
|
||
matrix on tag push (`v*`) and attaches binaries + `.sha256` sums to the
|
||
GitHub release. Runtime requirement: **none** (static).
|
||
|
||
## Troubleshooting
|
||
|
||
- **macOS Gatekeeper (“cannot be opened because Apple cannot check it for
|
||
malicious software”)** — remove the quarantine attribute:
|
||
`xattr -d com.apple.quarantine ./kei-mcp-server-darwin-arm64`
|
||
- **Windows SmartScreen / AV flags** — not signed; right-click →
|
||
Properties → Unblock, or add an AV exclusion for the binary path.
|
||
- **Missing symbol at startup** — usually a native-only dep that resolved
|
||
at runtime on Node but cannot be bundled. Re-run `bun install`, then
|
||
`bun build --compile ... --smol` to surface the resolution error.
|
||
- **`.js` ESM imports fail** — the mcp-server source imports via `.js`
|
||
suffix (ESM canonical). Bun resolves these from the sibling `.ts`
|
||
file automatically; no `tsc` pre-step needed.
|
||
|
||
## Lockfile
|
||
|
||
Since v0.19.1 the `_ts_packages` workspace ships a **single** `bun.lock`
|
||
at the workspace root (`_ts_packages/bun.lock`). Bun is a monorepo
|
||
tool — one lockfile covers all `packages/*` including mcp-server.
|
||
|
||
The release workflow runs `bun install --frozen-lockfile` from the
|
||
workspace root with NO fallback — a missing or out-of-date lockfile
|
||
fails the build on purpose. This is H4 supply-chain defense: every
|
||
release builds against the exact dependency tree recorded in the
|
||
committed lockfile, not whatever the npm registry serves that day.
|
||
|
||
**Before every release tag:**
|
||
1. `cd _ts_packages`
|
||
2. `bun install` (regenerates `bun.lock` if any `packages/*/package.json` changed)
|
||
3. Commit `bun.lock` if it changed
|
||
4. Tag the release
|
||
|
||
**If you see the build fail with "lockfile out of sync" on a tag push:**
|
||
you pushed the tag before committing an updated `bun.lock`. Fix:
|
||
generate the lockfile locally, commit, re-tag.
|
||
|
||
**Coexistence with `package-lock.json`:** the top-level CI (`ci.yml`)
|
||
still uses `npm ci` against `package-lock.json` for TypeScript tests.
|
||
Both lockfiles are committed. Audit finding L2 (dual-lockfile skew
|
||
risk) is tracked for a future `v0.20` consolidation — pick one tool
|
||
across CI + release. Until then, re-run `bun install` AND
|
||
`npm install` whenever any `packages/*/package.json` changes.
|