Skip to content

Pkgs

A pkg (package) is a self-contained directory with a manifest.json plus whatever it contributes — a UI panel, a tool server, an engine adapter, a background worker, or Claude Code skills and commands. Everything in Ikenga beyond the bare window chrome is a pkg.

At boot, the shell’s kernel discovers installed pkgs, validates each manifest against the schema, and registers every block it declares with the matching registry (UI routes, MCP servers, sidecars, cron, settings, and more). The manifest is the contract. The source, build output, and README are yours.

All published pkgs ship Apache-2.0 and live in one canonical monorepo, ikenga-pkgs, under packages/<type>/<slug>/.

Pick the smallest archetype that fits what your pkg contributes. A single pkg can combine several — the kernel walks whatever blocks are present and registers each.

ArchetypeWhat it contributesPick it when
UI iframeA panel that renders your own HTML/React in the shell, served by the kernel’s in-process content server.You’re shipping a mini-app, dashboard, form, or panel you control end to end and it’s happy inside an iframe.
UI webviewA native child webview (not an iframe).You need to drive a third-party site that refuses iframe embedding (via CSP frame-ancestors or X-Frame-Options), or you want per-pkg cookie isolation that survives reinstall.
MCP serverTools the AI engine can call, over the Model Context Protocol.You’re surfacing capabilities for the agent to invoke — read data, hit an API, kick off a workflow.
Engine adapterA new AI backend the shell can use as the chat engine.You’re integrating a CLI-based AI engine (see Engines).
SidecarA supervised, long-running bundled binary.You have a worker that doesn’t fit the MCP shape — a preview server, a render worker, a websocket client — and want explicit lifecycle control.
Skill-onlyClaude Code skills, slash commands, and/or agents — no UI, no process.The functionality is pure prompt and workflow. The simplest possible pkg.

Every pkg has a manifest.json at its root. A minimal UI-iframe manifest:

{
"id": "com.example.dashboard",
"name": "Dashboard",
"version": "0.1.0",
"ikenga_api": "1",
"kind": "embedded",
"author": { "name": "Example", "key": "example" },
"ui": {
"routes": [
{ "path": "/", "kind": "iframe", "source": "dist/index.html" }
]
}
}

Beyond ui, a manifest may declare any subset of mcp, sidecars, engine, skills, commands, agents, iyke, cron, settings, capabilities, and permissions. The ikenga_api field is the numeric host-API version your pkg targets (currently "1"); the host supports the current version and the one before it.

UI routes accept three kinds: "iframe", "webview", and "component" (the last is reserved for host-builtin React components — third-party component routes won’t mount).

A pkg only gets what its manifest asks for.

  • capabilities are opt-in, host-resolved features. The two that exist today are Supabase (the shell threads credentials from its encrypted vault through the handshake at mount time, so you never bake keys into a build) and webview child windows (capabilities.webview.child_webviews plus a declared list of cookie partitions). A "webview" route won’t mount unless the matching capability is declared.

  • permissions are scoped grants the kernel checks: shell.execute (which commands may be spawned), net (URL prefixes), fs.read / fs.write (path globs, which may use $pkg_data, $pkg_install, $home). Asking for fs.write outside your own $pkg_data triggers the trust gate — that pkg won’t auto-trust on install, and the user is prompted to consent (the “share kola” ritual). A pkg with an empty permissions block and no sensitive capabilities auto-trusts.

A UI-iframe pkg is an MCP App client. When the shell mounts your iframe, it performs an AppBridge handshake and delivers a hostContext — the current theme, host style variables, and (if you declared the capability and the vault is populated) Supabase credentials.

The rules that matter:

  • Register your handlers before you connect — the host may emit notifications synchronously right after the initialize response.
  • Handle onhostcontextchanged idempotently: the shell re-emits hostContext whenever the theme changes.
  • Because the handshake is async, you can’t construct a Supabase client at module-eval time — use a lazy getter that runs after hostContext arrives.
  • Run standalone (outside the shell) and the handshake is skipped, so build a sensible fallback for local dev.

The handshake uses @modelcontextprotocol/ext-apps. The Build your first pkg tutorial walks the whole flow.

PhaseWhat happens
Installikenga add <pkg> resolves the pkg, validates its manifest, runs the trust check, and registers every declared block with the kernel. Auto-trusts if there are no sensitive permissions; otherwise prompts.
BootThe kernel re-discovers installed pkgs and replays their registrations. Long-lived MCP servers and sidecars spawn here.
Updateikenga update pulls a newer version through the same validate-then-register path. If a pkg gained sensitive permissions since last install, the user is re-prompted to consent.
Remove (Retire)The kernel unregisters every block the pkg contributed. Skill-only pkgs also remove the content they copied into ~/.claude/.

Long-lived MCP servers and sidecars run under a supervisor with a full state machine — Spawning → Running, auto-restart on crash, a 3-strikes-in-60s circuit breaker that parks a flapping process, and port-in-use detection. The shell can stream lifecycle events to the UI.

CLIJobCommands
ikengaDisk-side package manager — mutates what’s installed.list, add, update, remove, dev <path>
iykeRuntime controller — drives a shell that’s already running over its localhost bridge.navigate panes, switch modes, inspect state

ikenga dev <path> is the developer loop: it symlinks a pkg into the running shell, auto-trusts the source, and hot-reloads on manifest changes — no shell restart. Iframe code changes flow through your dev server’s HMR; sidecar and MCP source changes restart through the supervisor’s file watcher; Ctrl-C unregisters cleanly. See the Build your first pkg tutorial.